mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
rewrite ipc communication; do ipc message reception on separate thread, wake up main thread; fix various robustness issues. do not necessarily initialize slower-to-initialize layers in conversion/ipc instances
This commit is contained in:
+19
-22
@@ -18,65 +18,62 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum
|
||||
{
|
||||
ProfBeginCapture(arguments[0]);
|
||||
}
|
||||
#if defined(OS_CORE_H)
|
||||
#if defined(OS_CORE_H) && !defined(OS_INIT_MANUAL)
|
||||
os_init();
|
||||
#endif
|
||||
#if defined(TASK_SYSTEM_H)
|
||||
#if defined(TASK_SYSTEM_H) && !defined(TS_INIT_MANUAL)
|
||||
ts_init();
|
||||
#endif
|
||||
#if defined(HASH_STORE_H)
|
||||
#if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL)
|
||||
hs_init();
|
||||
#endif
|
||||
#if defined(FILE_STREAM_H)
|
||||
#if defined(FILE_STREAM_H) && !defined(FS_INIT_MANUAL)
|
||||
fs_init();
|
||||
#endif
|
||||
#if defined(TEXT_CACHE_H)
|
||||
#if defined(TEXT_CACHE_H) && !defined(TXT_INIT_MANUAL)
|
||||
txt_init();
|
||||
#endif
|
||||
#if defined(DASM_CACHE_H)
|
||||
#if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL)
|
||||
dasm_init();
|
||||
#endif
|
||||
#if defined(DBGI_H)
|
||||
dbgi_init();
|
||||
#endif
|
||||
#if defined(DI_H)
|
||||
#if defined(DI_H) && !defined(DI_INIT_MANUAL)
|
||||
di_init();
|
||||
#endif
|
||||
#if defined(FUZZY_SEARCH_H)
|
||||
#if defined(FUZZY_SEARCH_H) && !defined(FZY_INIT_MANUAL)
|
||||
fzy_init();
|
||||
#endif
|
||||
#if defined(TXTI_H)
|
||||
#if defined(TXTI_H) && !defined(TXTI_INIT_MANUAL)
|
||||
txti_init();
|
||||
#endif
|
||||
#if defined(DEMON_CORE_H)
|
||||
#if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL)
|
||||
dmn_init();
|
||||
#endif
|
||||
#if defined(CTRL_CORE_H)
|
||||
#if defined(CTRL_CORE_H) && !defined(CTRL_INIT_MANUAL)
|
||||
ctrl_init();
|
||||
#endif
|
||||
#if defined(OS_GRAPHICAL_H)
|
||||
#if defined(OS_GRAPHICAL_H) && !defined(OS_GFX_INIT_MANUAL)
|
||||
os_graphical_init();
|
||||
#endif
|
||||
#if defined(FONT_PROVIDER_H)
|
||||
#if defined(FONT_PROVIDER_H) && !defined(FP_INIT_MANUAL)
|
||||
fp_init();
|
||||
#endif
|
||||
#if defined(RENDER_CORE_H)
|
||||
#if defined(RENDER_CORE_H) && !defined(R_INIT_MANUAL)
|
||||
r_init(&cmdline);
|
||||
#endif
|
||||
#if defined(TEXTURE_CACHE_H)
|
||||
#if defined(TEXTURE_CACHE_H) && !defined(TEX_INIT_MANUAL)
|
||||
tex_init();
|
||||
#endif
|
||||
#if defined(GEO_CACHE_H)
|
||||
#if defined(GEO_CACHE_H) && !defined(GEO_INIT_MANUAL)
|
||||
geo_init();
|
||||
#endif
|
||||
#if defined(FONT_CACHE_H)
|
||||
#if defined(FONT_CACHE_H) && !defined(F_INIT_MANUAL)
|
||||
f_init();
|
||||
#endif
|
||||
#if defined(DF_CORE_H)
|
||||
#if defined(DF_CORE_H) && !defined(DF_INIT_MANUAL)
|
||||
DF_StateDeltaHistory *hist = df_state_delta_history_alloc();
|
||||
df_core_init(&cmdline, hist);
|
||||
#endif
|
||||
#if defined(DF_GFX_H)
|
||||
#if defined(DF_GFX_H) && !defined(DF_GFX_INIT_MANUAL)
|
||||
df_gfx_init(update_and_render, df_state_delta_history());
|
||||
#endif
|
||||
entry_point(&cmdline);
|
||||
|
||||
@@ -6379,6 +6379,7 @@ internal void
|
||||
df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
{
|
||||
// rjf: log
|
||||
if(params->os_event == 0 || params->os_event->kind != OS_EventKind_MouseMove)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_Entity *entity = df_entity_from_handle(params->entity);
|
||||
|
||||
@@ -333,7 +333,7 @@ DF_CoreCmdTable:// | | |
|
||||
{DuplicateEntity 1 Null Nil 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" }
|
||||
|
||||
//- rjf: breakpoints
|
||||
{TextBreakpoint 1 Null Nil 0 0 0 0 0 0 CircleFilled "text_breakpoint" "Text Breakpoint" "Places or removes a breakpoint on the specified line of source code." "" }
|
||||
{TextBreakpoint 1 FilePath Nil 0 0 0 0 0 0 CircleFilled "text_breakpoint" "Text Breakpoint" "Places or removes a breakpoint on the specified line of source code." "" }
|
||||
{AddressBreakpoint 0 VirtualAddr Nil 0 0 0 0 1 1 CircleFilled "address_breakpoint" "Address Breakpoint" "Places or removes a breakpoint on the specified address." "" }
|
||||
{FunctionBreakpoint 0 String Nil 0 0 0 0 1 1 CircleFilled "function_breakpoint" "Function Breakpoint" "Places or removes a breakpoint on the first address(es) of the specified function." "" }
|
||||
{ToggleBreakpointAtCursor 0 Null Nil 0 0 0 0 0 0 CircleFilled "toggle_breakpoint_cursor" "Toggle Breakpoint At Cursor" "Places or removes a breakpoint on the line on which the active cursor sits." "" }
|
||||
|
||||
@@ -374,7 +374,7 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] =
|
||||
{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp("Name Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("edit_entity"), str8_lit_comp("Opens the editor for an entity."), str8_lit_comp(""), str8_lit_comp("Edit Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("text_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified line of source code."), str8_lit_comp(""), str8_lit_comp("Text Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("text_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified line of source code."), str8_lit_comp(""), str8_lit_comp("Text Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("address_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("Address Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("function_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("Function Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("toggle_breakpoint_cursor"), str8_lit_comp("Places or removes a breakpoint on the line on which the active cursor sits."), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint At Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
|
||||
|
||||
+2
-1
@@ -1039,7 +1039,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//////////////////////////////
|
||||
//- rjf: unpack context
|
||||
//
|
||||
B32 window_is_focused = os_window_is_focused(ws->os);
|
||||
B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc;
|
||||
B32 confirm_open = df_gfx_state->confirm_active;
|
||||
B32 query_is_open = !df_view_is_nil(ws->query_view_stack_top);
|
||||
B32 hover_eval_is_open = (!confirm_open &&
|
||||
@@ -1050,6 +1050,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
{
|
||||
ws->menu_bar_key_held = 0;
|
||||
}
|
||||
ws->window_temporarily_focused_ipc = 0;
|
||||
ui_select_state(ws->ui);
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
@@ -513,6 +513,7 @@ struct DF_Window
|
||||
UI_State *ui;
|
||||
F32 code_font_size_delta;
|
||||
F32 main_font_size_delta;
|
||||
B32 window_temporarily_focused_ipc;
|
||||
|
||||
// rjf: view state delta history
|
||||
DF_StateDeltaHistory *view_state_hist;
|
||||
|
||||
@@ -1607,7 +1607,7 @@ os_semaphore_close(OS_Handle semaphore)
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_semaphore_take(OS_Handle semaphore)
|
||||
os_semaphore_take(OS_Handle semaphore, U64 endt_us)
|
||||
{
|
||||
NotImplemented;
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -393,7 +393,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal CTRL_WAKEUP_FUNCTION_DEF(wakeup_hook)
|
||||
internal CTRL_WAKEUP_FUNCTION_DEF(wakeup_hook_ctrl)
|
||||
{
|
||||
os_send_wakeup_event();
|
||||
}
|
||||
|
||||
+14
-3
@@ -401,12 +401,23 @@ struct IPCInfo
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
#define IPC_SHARED_MEMORY_BUFFER_SIZE MB(16)
|
||||
//- rjf: IPC resources
|
||||
#define IPC_SHARED_MEMORY_BUFFER_SIZE MB(4)
|
||||
StaticAssert(IPC_SHARED_MEMORY_BUFFER_SIZE > sizeof(IPCInfo), ipc_buffer_size_requirement);
|
||||
read_only global String8 ipc_shared_memory_name = str8_lit_comp("_raddbg_ipc_shared_memory_");
|
||||
read_only global String8 ipc_semaphore_name = str8_lit_comp("_raddbg_ipc_semaphore_");
|
||||
global OS_Handle ipc_signal_semaphore = {0};
|
||||
global OS_Handle ipc_lock_semaphore = {0};
|
||||
global U8 *ipc_shared_memory_base = 0;
|
||||
global U8 ipc_s2m_ring_buffer[MB(4)] = {0};
|
||||
global U64 ipc_s2m_ring_write_pos = 0;
|
||||
global U64 ipc_s2m_ring_read_pos = 0;
|
||||
global OS_Handle ipc_s2m_ring_mutex = {0};
|
||||
global OS_Handle ipc_s2m_ring_cv = {0};
|
||||
|
||||
//- rjf: frame time history
|
||||
global U64 frame_time_us_history[64] = {0};
|
||||
global U64 frame_time_us_history_idx = 0;
|
||||
|
||||
//- rjf: main thread log
|
||||
global Log *main_thread_log = 0;
|
||||
global String8 main_thread_log_path = {0};
|
||||
|
||||
|
||||
+184
-60
@@ -11,6 +11,13 @@
|
||||
#define BUILD_TITLE "The RAD Debugger"
|
||||
#define OS_FEATURE_GRAPHICAL 1
|
||||
|
||||
#define R_INIT_MANUAL 1
|
||||
#define TEX_INIT_MANUAL 1
|
||||
#define GEO_INIT_MANUAL 1
|
||||
#define F_INIT_MANUAL 1
|
||||
#define DF_INIT_MANUAL 1
|
||||
#define DF_GFX_INIT_MANUAL 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
@@ -100,6 +107,42 @@
|
||||
#include "df/df_inc.c"
|
||||
#include "raddbg.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IPC Signaler Thread
|
||||
|
||||
internal void
|
||||
ipc_signaler_thread__entry_point(void *p)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(os_semaphore_take(ipc_signal_semaphore, max_U64))
|
||||
{
|
||||
if(os_semaphore_take(ipc_lock_semaphore, max_U64))
|
||||
{
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
String8 msg = str8((U8 *)(ipc_info+1), ipc_info->msg_size);
|
||||
msg.size = Min(msg.size, IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo));
|
||||
OS_MutexScope(ipc_s2m_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
|
||||
U64 available_size = (sizeof(ipc_s2m_ring_buffer) - unconsumed_size);
|
||||
if(available_size >= sizeof(U64)+sizeof(msg.size))
|
||||
{
|
||||
ipc_s2m_ring_write_pos += ring_write_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, &msg.size);
|
||||
ipc_s2m_ring_write_pos += ring_write(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, msg.str, msg.size);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(ipc_s2m_ring_cv, ipc_s2m_ring_mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(ipc_s2m_ring_cv);
|
||||
os_send_wakeup_event();
|
||||
ipc_info->msg_size = 0;
|
||||
os_semaphore_drop(ipc_lock_semaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entry Point
|
||||
|
||||
@@ -178,7 +221,7 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
|
||||
//- rjf: set up layers
|
||||
ctrl_set_wakeup_hook(wakeup_hook);
|
||||
ctrl_set_wakeup_hook(wakeup_hook_ctrl);
|
||||
|
||||
//- rjf: dispatch to top-level codepath based on execution mode
|
||||
switch(exec_mode)
|
||||
@@ -187,12 +230,16 @@ entry_point(CmdLine *cmd_line)
|
||||
default:
|
||||
case ExecMode_Normal:
|
||||
{
|
||||
//- rjf: set up shared memory for ipc
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
void *ipc_shared_memory_base = os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
OS_Handle ipc_semaphore = os_semaphore_alloc(1, 1, ipc_semaphore_name);
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
ipc_info->msg_size = 0;
|
||||
//- rjf: manual layer initialization
|
||||
{
|
||||
r_init(cmd_line);
|
||||
tex_init();
|
||||
geo_init();
|
||||
f_init();
|
||||
DF_StateDeltaHistory *hist = df_state_delta_history_alloc();
|
||||
df_core_init(cmd_line, hist);
|
||||
df_gfx_init(update_and_render, df_state_delta_history());
|
||||
}
|
||||
|
||||
//- rjf: setup initial target from command line args
|
||||
{
|
||||
@@ -247,56 +294,97 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: set up shared resources for ipc to this instance; launch IPC signaler thread
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U32 instance_pid = os_get_pid();
|
||||
String8 ipc_shared_memory_name = push_str8f(scratch.arena, "_raddbg_ipc_shared_memory_%i_", instance_pid);
|
||||
String8 ipc_signal_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_signal_semaphore_%i_", instance_pid);
|
||||
String8 ipc_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_lock_semaphore_%i_", instance_pid);
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
ipc_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
ipc_signal_semaphore = os_semaphore_alloc(0, 1, ipc_signal_semaphore_name);
|
||||
ipc_lock_semaphore = os_semaphore_alloc(1, 1, ipc_lock_semaphore_name);
|
||||
ipc_s2m_ring_mutex = os_mutex_alloc();
|
||||
ipc_s2m_ring_cv = os_condition_variable_alloc();
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
MemoryZeroStruct(ipc_info);
|
||||
os_launch_thread(ipc_signaler_thread__entry_point, 0, 0);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: main application loop
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
//- rjf: get IPC messages & dispatch ui commands from them
|
||||
//- rjf: consume IPC messages, dispatch UI commands
|
||||
{
|
||||
if(os_semaphore_take(ipc_semaphore, max_U64))
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 consumed = 0;
|
||||
String8 msg = {0};
|
||||
OS_MutexScope(ipc_s2m_ring_mutex)
|
||||
{
|
||||
if(ipc_info->msg_size != 0)
|
||||
U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(U64))
|
||||
{
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 msg_size = ipc_info->msg_size;
|
||||
String8 cmd_string = str8(buffer, msg_size);
|
||||
ipc_info->msg_size = 0;
|
||||
DF_Window *dst_window = df_gfx_state->first_window;
|
||||
for(DF_Window *window = dst_window; window != 0; window = window->next)
|
||||
consumed = 1;
|
||||
ipc_s2m_ring_read_pos += ring_read_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, &msg.size);
|
||||
msg.size = Min(msg.size, unconsumed_size);
|
||||
msg.str = push_array(scratch.arena, U8, msg.size);
|
||||
ipc_s2m_ring_read_pos += ring_read(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, msg.str, msg.size);
|
||||
}
|
||||
}
|
||||
if(consumed)
|
||||
{
|
||||
os_condition_variable_broadcast(ipc_s2m_ring_cv);
|
||||
}
|
||||
if(msg.size != 0)
|
||||
{
|
||||
log_infof("IPC message received: \"%S\"", msg);
|
||||
DF_Window *dst_window = df_gfx_state->first_window;
|
||||
for(DF_Window *window = dst_window; window != 0; window = window->next)
|
||||
{
|
||||
if(os_window_is_focused(window->os))
|
||||
{
|
||||
if(os_window_is_focused(window->os))
|
||||
{
|
||||
dst_window = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dst_window != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 cmd_spec_string = df_cmd_name_part_from_string(cmd_string);
|
||||
DF_CmdSpec *cmd_spec = df_cmd_spec_from_string(cmd_spec_string);
|
||||
if(!df_cmd_spec_is_nil(cmd_spec))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_gfx();
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_window(dst_window);
|
||||
String8 error = df_cmd_params_apply_spec_query(scratch.arena, &ctrl_ctx, ¶ms, cmd_spec, df_cmd_arg_part_from_string(cmd_string));
|
||||
if(error.size == 0)
|
||||
{
|
||||
df_push_cmd__root(¶ms, cmd_spec);
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = error;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
dst_window = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dst_window != 0)
|
||||
{
|
||||
dst_window->window_temporarily_focused_ipc = 1;
|
||||
String8 cmd_spec_string = df_cmd_name_part_from_string(msg);
|
||||
DF_CmdSpec *cmd_spec = df_cmd_spec_from_string(cmd_spec_string);
|
||||
if(!df_cmd_spec_is_nil(cmd_spec))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_window(dst_window);
|
||||
String8 error = df_cmd_params_apply_spec_query(scratch.arena, &ctrl_ctx, ¶ms, cmd_spec, df_cmd_arg_part_from_string(msg));
|
||||
if(error.size == 0)
|
||||
{
|
||||
df_push_cmd__root(¶ms, cmd_spec);
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = error;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = push_str8f(scratch.arena, "\"%S\" is not a command.", cmd_spec_string);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
}
|
||||
os_semaphore_drop(ipc_semaphore);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: update & render frame
|
||||
@@ -344,25 +432,61 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//- rjf: grab ipc shared memory
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_open(ipc_shared_memory_name);
|
||||
void *ipc_shared_memory_base = os_shared_memory_view_open(ipc_shared_memory, r1u64(0, MB(16)));
|
||||
if(ipc_shared_memory_base != 0)
|
||||
//- rjf: grab explicit PID argument
|
||||
U32 dst_pid = 0;
|
||||
if(cmd_line_has_argument(cmd_line, str8_lit("pid")))
|
||||
{
|
||||
OS_Handle ipc_semaphore = os_semaphore_open(ipc_semaphore_name);
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
if(os_semaphore_take(ipc_semaphore, os_now_microseconds() + Million(6)))
|
||||
String8 dst_pid_string = cmd_line_string(cmd_line, str8_lit("pid"));
|
||||
U64 dst_pid_u64 = 0;
|
||||
if(dst_pid_string.size != 0 &&
|
||||
try_u64_from_str8_c_rules(dst_pid_string, &dst_pid_u64))
|
||||
{
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo);
|
||||
StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
|
||||
String8 msg = str8_list_join(scratch.arena, &cmd_line->inputs, &join);
|
||||
ipc_info->msg_size = Min(buffer_max, msg.size);
|
||||
MemoryCopy(buffer, msg.str, ipc_info->msg_size);
|
||||
os_semaphore_drop(ipc_semaphore);
|
||||
dst_pid = (U32)dst_pid_u64;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: no explicit PID? -> find PID to send message to, by looking for other raddbg instances
|
||||
if(dst_pid == 0)
|
||||
{
|
||||
U32 this_pid = os_get_pid();
|
||||
DMN_ProcessIter it = {0};
|
||||
dmn_process_iter_begin(&it);
|
||||
for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &it, &info);)
|
||||
{
|
||||
if(str8_match(str8_skip_last_slash(str8_chop_last_dot(cmd_line->exe_name)), str8_skip_last_slash(str8_chop_last_dot(info.name)), StringMatchFlag_CaseInsensitive) &&
|
||||
this_pid != info.pid)
|
||||
{
|
||||
dst_pid = info.pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dmn_process_iter_end(&it);
|
||||
}
|
||||
|
||||
//- rjf: grab destination instance's shared memory resources
|
||||
String8 ipc_shared_memory_name = push_str8f(scratch.arena, "_raddbg_ipc_shared_memory_%i_", dst_pid);
|
||||
String8 ipc_signal_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_signal_semaphore_%i_", dst_pid);
|
||||
String8 ipc_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_lock_semaphore_%i_", dst_pid);
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
ipc_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
ipc_signal_semaphore = os_semaphore_alloc(0, 1, ipc_signal_semaphore_name);
|
||||
ipc_lock_semaphore = os_semaphore_alloc(1, 1, ipc_lock_semaphore_name);
|
||||
|
||||
//- rjf: got resources -> write message
|
||||
if(ipc_shared_memory_base != 0 &&
|
||||
os_semaphore_take(ipc_lock_semaphore, max_U64))
|
||||
{
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo);
|
||||
StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
|
||||
String8 msg = str8_list_join(scratch.arena, &cmd_line->inputs, &join);
|
||||
ipc_info->msg_size = Min(buffer_max, msg.size);
|
||||
MemoryCopy(buffer, msg.str, ipc_info->msg_size);
|
||||
os_semaphore_drop(ipc_signal_semaphore);
|
||||
os_semaphore_drop(ipc_lock_semaphore);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user