static VALUE rb_monitor_run_bang(VALUE self) { BOOL already_running, waiting_succeeded; WDM_PMonitor monitor; WDM_DEBUG("Running the monitor!"); Data_Get_Struct(self, WDM_Monitor, monitor); already_running = FALSE; EnterCriticalSection(&monitor->lock); if ( monitor->running ) { already_running = TRUE; } else { monitor->running = TRUE; } LeaveCriticalSection(&monitor->lock); if (already_running) { WDM_DEBUG("Not doing anything because the monitor is already running!"); return Qnil; } // Reset events ResetEvent(monitor->process_event); ResetEvent(monitor->stop_event); monitor->monitoring_thread = CreateThread( NULL, // default security attributes 0, // use default stack size start_monitoring, // thread function name monitor, // argument to thread function 0, // use default creation flags NULL // Ignore thread identifier ); if ( monitor->monitoring_thread == NULL ) { rb_raise(eWDM_Error, "Can't create a thread for the monitor!"); } while ( monitor->running ) { waiting_succeeded = rb_thread_blocking_region(wait_for_changes, monitor->process_event, stop_monitoring, monitor); if ( waiting_succeeded == Qfalse ) { rb_raise(eWDM_Error, "Failed while waiting for a change in the watched directories!"); } if ( ! monitor->running ) { wdm_queue_empty(monitor->changes); return Qnil; } process_changes(monitor->changes); if ( ! ResetEvent(monitor->process_event) ) { rb_raise(eWDM_Error, "Couldn't reset system events to watch for changes!"); } } return Qnil; }
static VALUE rb_monitor_run_bang(VALUE self) { BOOL already_running, waiting_succeeded; WDM_PMonitor monitor; WDM_DEBUG("Running the monitor!"); Data_Get_Struct(self, WDM_Monitor, monitor); already_running = FALSE; EnterCriticalSection(&monitor->lock); if ( monitor->running ) { already_running = TRUE; } else { monitor->running = TRUE; } LeaveCriticalSection(&monitor->lock); if (already_running) { WDM_DEBUG("Not doing anything because the monitor is already running!"); return Qnil; } // Reset events ResetEvent(monitor->process_event); ResetEvent(monitor->stop_event); monitor->monitoring_thread = CreateThread( NULL, // default security attributes 0, // use default stack size start_monitoring, // thread function name monitor, // argument to thread function 0, // use default creation flags NULL // Ignore thread identifier ); if ( monitor->monitoring_thread == NULL ) { rb_raise(eWDM_Error, "Can't create a thread for the monitor!"); } while ( monitor->running ) { // Ruby 2.2 removed the 'rb_thread_blocking_region' function. Hence, we now need // to check if the replacement function is defined and use it if it's available. #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL waiting_succeeded = rb_thread_call_without_gvl(wait_for_changes, monitor->process_event, stop_monitoring, monitor); #else waiting_succeeded = rb_thread_blocking_region(wait_for_changes, monitor->process_event, stop_monitoring, monitor); #endif if ( waiting_succeeded == Qfalse ) { rb_raise(eWDM_Error, "Failed while waiting for a change in the watched directories!"); } if ( ! monitor->running ) { wdm_queue_empty(monitor->changes); return Qnil; } process_changes(monitor->changes); if ( ! ResetEvent(monitor->process_event) ) { rb_raise(eWDM_Error, "Couldn't reset system events to watch for changes!"); } } return Qnil; }