示例#1
0
文件: rb_monitor.c 项目: caisong/wdm
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;
}
示例#2
0
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;
}