static void g_dbus_flush(DBusConnection *connection) { GSList *l; for (l = pending; l;) { struct generic_data *data = l->data; l = l->next; if (data->conn != connection) continue; process_changes(data); } }
static void generic_unregister(DBusConnection *connection, void *user_data) { struct generic_data *data = user_data; struct generic_data *parent = data->parent; if (parent != NULL) parent->objects = g_slist_remove(parent->objects, data); if (data->process_id > 0) { g_source_remove(data->process_id); process_changes(data); } g_slist_foreach(data->objects, reset_parent, data->parent); g_slist_free(data->objects); dbus_connection_unref(data->conn); g_free(data->introspect); g_free(data->path); g_free(data); }
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 DWORD CALLBACK watch_desktop_folders( LPVOID param ) { HWND hwnd = param; HRESULT init = CoInitialize( NULL ); HANDLE dir0, dir1, events[2]; OVERLAPPED ovl0, ovl1; char *buf0 = NULL, *buf1 = NULL; DWORD count, size = 4096, error = ERROR_OUTOFMEMORY; BOOL ret, redraw; dir0 = CreateFileW( desktop_folder, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL ); if (dir0 == INVALID_HANDLE_VALUE) return GetLastError(); dir1 = CreateFileW( desktop_folder_public, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL ); if (dir1 == INVALID_HANDLE_VALUE) { CloseHandle( dir0 ); return GetLastError(); } if (!(ovl0.hEvent = events[0] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error; if (!(ovl1.hEvent = events[1] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error; if (!(buf0 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error; if (!(buf1 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error; for (;;) { ret = ReadDirectoryChangesW( dir0, buf0, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl0, NULL ); if (!ret) { error = GetLastError(); goto error; } ret = ReadDirectoryChangesW( dir1, buf1, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl1, NULL ); if (!ret) { error = GetLastError(); goto error; } redraw = FALSE; switch ((error = WaitForMultipleObjects( 2, events, FALSE, INFINITE ))) { case WAIT_OBJECT_0: if (!GetOverlappedResult( dir0, &ovl0, &count, FALSE ) || !count) break; if (process_changes( desktop_folder, buf0 )) redraw = TRUE; break; case WAIT_OBJECT_0 + 1: if (!GetOverlappedResult( dir1, &ovl1, &count, FALSE ) || !count) break; if (process_changes( desktop_folder_public, buf1 )) redraw = TRUE; break; default: goto error; } if (redraw) InvalidateRect( hwnd, NULL, TRUE ); } error: CloseHandle( dir0 ); CloseHandle( dir1 ); CloseHandle( events[0] ); CloseHandle( events[1] ); HeapFree( GetProcessHeap(), 0, buf0 ); HeapFree( GetProcessHeap(), 0, buf1 ); if (SUCCEEDED( init )) CoUninitialize(); return error; }
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; }