swap without events
This commit is contained in:
parent
05f6c937cb
commit
a8bc77fab3
@ -126,7 +126,7 @@ String SwappedStateFromName(Arena *arena, String name)
|
||||
{
|
||||
TempArena scratch = BeginScratch(arena);
|
||||
String result = ZI;
|
||||
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name));
|
||||
String path = StringF(scratch.arena, "ppswap/%F.swp", FmtString(name));
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, path);
|
||||
HANDLE handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
@ -154,8 +154,10 @@ String SwappedStateFromName(Arena *arena, String name)
|
||||
void WriteSwappedState(String name, String data)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
/* TODO: Use directory non-relative to executable */
|
||||
CreateDirectoryW(L"ppswap", 0);
|
||||
String result = ZI;
|
||||
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name));
|
||||
String path = StringF(scratch.arena, "ppswap/%F.swp", FmtString(name));
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, path);
|
||||
HANDLE handle = CreateFileW(path_wstr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
@ -316,11 +318,6 @@ i32 W32_Main(void)
|
||||
}
|
||||
|
||||
/* Set up exit events */
|
||||
#if HotSwappingIsEnabled
|
||||
g->swap_event = CreateEventW(0, 1, 0, L"Local\\pp_swap_start");
|
||||
#else
|
||||
g->swap_event = CreateEventW(0, 1, 0, 0);
|
||||
#endif
|
||||
g->panic_event = CreateEventW(0, 1, 0, 0);
|
||||
g->startup_end_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_begin_event = CreateEventW(0, 1, 0, 0);
|
||||
@ -369,7 +366,6 @@ i32 W32_Main(void)
|
||||
HANDLE handles[] = {
|
||||
g->exit_begin_event,
|
||||
g->panic_event,
|
||||
g->swap_event,
|
||||
};
|
||||
DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
}
|
||||
|
||||
@ -38,7 +38,6 @@ Struct(W32_SharedState)
|
||||
Atomic32 panicking;
|
||||
wchar_t panic_wstr[4096];
|
||||
HANDLE panic_event;
|
||||
HANDLE swap_event;
|
||||
HANDLE startup_end_event;
|
||||
HANDLE exit_begin_event;
|
||||
HANDLE exit_end_event;
|
||||
|
||||
@ -100,36 +100,6 @@ LineCol LineColFromPos(String data, i64 pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Swap
|
||||
|
||||
#if PlatformIsWindows
|
||||
u64 SignalSwapStart(void)
|
||||
{
|
||||
OS_Mkdir(Lit("swap"));
|
||||
HANDLE swap_end_event = CreateEventW(0, 1, 0, L"Local\\pp_swap_end");
|
||||
HANDLE swap_start_event = OpenEventW(EVENT_MODIFY_STATE, 0, L"Local\\pp_swap_start");
|
||||
if (swap_start_event != 0)
|
||||
{
|
||||
SetEvent(swap_start_event);
|
||||
CloseHandle(swap_start_event);
|
||||
}
|
||||
return (u64)swap_end_event;
|
||||
}
|
||||
|
||||
void WaitForSwapEnd(u64 swap_start, i64 timeout_ns)
|
||||
{
|
||||
HANDLE swap_start_event = (HANDLE)swap_start;
|
||||
if (swap_start_event != 0)
|
||||
{
|
||||
DWORD timeout_ms = timeout_ns / 1000000;
|
||||
WaitForSingleObject(swap_start_event, timeout_ms);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# error Swap signaling not implemented
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ OS command job
|
||||
|
||||
@ -905,8 +875,6 @@ JobDef(Build, _, __)
|
||||
}
|
||||
}
|
||||
|
||||
u64 swap_start = SignalSwapStart();
|
||||
|
||||
//////////////////////////////
|
||||
//- Args
|
||||
|
||||
@ -1085,9 +1053,14 @@ JobDef(Build, _, __)
|
||||
|
||||
//- Link
|
||||
|
||||
WaitForSwapEnd(swap_start, NsFromSeconds(0.5f / 1000.f));
|
||||
|
||||
String exe_file = Lit("pp.exe");
|
||||
{
|
||||
/* Wait for exe to become writable (once program closes) */
|
||||
i64 timeout_ns = NsFromSeconds(0.5);
|
||||
OS_File file = OS_OpenFile(exe_file, OS_FileFlag_Write, timeout_ns);
|
||||
OS_CloseFile(file);
|
||||
}
|
||||
|
||||
i64 link_elapsed_ns = 0;
|
||||
if (ret == 0)
|
||||
{
|
||||
|
||||
@ -87,7 +87,7 @@ String F_ExtensionFromFile(String path)
|
||||
String F_DataFromFile(Arena *arena, String path)
|
||||
{
|
||||
String result = ZI;
|
||||
OS_File file = OS_OpenFile(path, OS_FileFlag_Read);
|
||||
OS_File file = OS_OpenFile(path, OS_FileFlag_Read, I64Max);
|
||||
result = OS_ReadEntireFile(arena, file);
|
||||
OS_CloseFile(file);
|
||||
return result;
|
||||
@ -98,7 +98,7 @@ String F_DataFromFile(Arena *arena, String path)
|
||||
|
||||
void F_ClearWrite(String path, String data)
|
||||
{
|
||||
OS_File file = OS_OpenFile(path, OS_FileFlag_Write | OS_FileFlag_Create);
|
||||
OS_File file = OS_OpenFile(path, OS_FileFlag_Write | OS_FileFlag_Create, I64Max);
|
||||
OS_ClearWriteFile(file, data);
|
||||
OS_CloseFile(file);
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ Enum(OS_FileFlag)
|
||||
OS_FileFlag_Read = (1 << 0),
|
||||
OS_FileFlag_Write = (1 << 1),
|
||||
OS_FileFlag_Create = (1 << 2),
|
||||
OS_FileFlag_NoWait = (1 << 3)
|
||||
};
|
||||
|
||||
Struct(OS_File)
|
||||
@ -32,7 +31,7 @@ void OS_Startup(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl File system operations
|
||||
|
||||
OS_File OS_OpenFile(String path, OS_FileFlag flags);
|
||||
OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns);
|
||||
void OS_CloseFile(OS_File file);
|
||||
String OS_ReadEntireFile(Arena *arena, OS_File file);
|
||||
void OS_ClearWriteFile(OS_File file, String data);
|
||||
|
||||
@ -35,30 +35,29 @@ void OS_Startup(void)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdef File system hooks
|
||||
|
||||
OS_File OS_OpenFile(String path, OS_FileFlag flags)
|
||||
OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
OS_File result = ZI;
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, path);
|
||||
b32 wait_for_access = 1;
|
||||
u32 share_mode = FILE_SHARE_READ;
|
||||
u32 create_mode = OPEN_EXISTING;
|
||||
u32 access_flags = 0;
|
||||
if (flags & OS_FileFlag_Read) access_flags |= GENERIC_READ;
|
||||
if (flags & OS_FileFlag_Write) access_flags |= GENERIC_WRITE;
|
||||
if (flags & OS_FileFlag_Create) create_mode = OPEN_ALWAYS;
|
||||
if (flags & OS_FileFlag_NoWait) wait_for_access = 0;
|
||||
i32 timeout_ms = timeout_ns / 1000000;
|
||||
i32 elapsed_ms = 0;
|
||||
i32 delay_ms = 1;
|
||||
HANDLE handle;
|
||||
while ((handle = CreateFileW(path_wstr, access_flags, share_mode, 0, create_mode, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE && wait_for_access)
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
for (;;)
|
||||
{
|
||||
if (GetLastError() == ERROR_SHARING_VIOLATION)
|
||||
handle = CreateFileW(path_wstr, access_flags, share_mode, 0, create_mode, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE && elapsed_ms < timeout_ms && GetLastError() == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
Sleep(delay_ms);
|
||||
if (delay_ms < 1024)
|
||||
{
|
||||
delay_ms *= 2;
|
||||
}
|
||||
elapsed_ms += delay_ms;
|
||||
delay_ms = MinI32(delay_ms * 2, 1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -92,7 +92,6 @@ ExitFuncDef(ShutdownUser)
|
||||
SwappedUserState *swap = PushStruct(scratch.arena, SwappedUserState);
|
||||
swap->s = *g;
|
||||
WriteSwappedState(Lit("pp_user"), StringFromStruct(swap));
|
||||
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user