/* Signal to the main thread that we have file notifications for it to process. */ static void send_notifications (BYTE *info, DWORD info_size, void *desc, volatile int *terminate) { int done = 0; struct frame *f = SELECTED_FRAME (); /* A single buffer is used to communicate all notifications to the main thread. Since both the main thread and several watcher threads could be active at the same time, we use a critical area and an "in-use" flag to synchronize them. A watcher thread can only put its notifications in the buffer if it acquires the critical area and finds the "in-use" flag reset. The main thread resets the flag after it is done processing notifications. FIXME: is there a better way of dealing with this? */ while (!done && !*terminate) { enter_crit (); if (!notification_buffer_in_use) { if (info_size) memcpy (file_notifications, info, min (info_size, sizeof (file_notifications))); notifications_size = min (info_size, sizeof (file_notifications)); notifications_desc = desc; /* If PostMessage fails, the message queue is full. If that happens, the last thing they will worry about is file notifications. So we effectively discard the notification in that case. */ if ((FRAME_TERMCAP_P (f) /* We send the message to the main (a.k.a. "Lisp") thread, where it will wake up MsgWaitForMultipleObjects inside sys_select, causing it to report that there's some keyboard input available. This will in turn cause w32_console_read_socket to be called, which will pick up the file notifications. */ && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0)) || (FRAME_W32_P (f) && PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0)) /* When we are running in batch mode, there's no one to send a message, so we just signal the data is available and hope sys_select will be called soon and will read the data. */ || (FRAME_INITIAL_P (f) && noninteractive)) notification_buffer_in_use = 1; done = 1; } leave_crit (); if (!done) Sleep (5); } }
/* Signal to the main thread that we have file notifications for it to process. */ static void send_notifications (struct notifications_set *ns) { struct frame *f = SELECTED_FRAME (); /* We add the current notification set to the linked list. Use the critical section to make sure only one thread will access the linked list. */ enter_crit (); ns->next = notifications_set_head; ns->prev = notifications_set_head->prev; ns->prev->next = ns; notifications_set_head->prev = ns; leave_crit(); /* If PostMessage fails, the message queue is full. If that happens, the last thing they will worry about is file notifications. So we effectively discard the notification in that case. */ if (FRAME_TERMCAP_P (f)) /* We send the message to the main (a.k.a. "Lisp") thread, where it will wake up MsgWaitForMultipleObjects inside sys_select, causing it to report that there's some keyboard input available. This will in turn cause w32_console_read_socket to be called, which will pick up the file notifications. */ PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0); else if (FRAME_W32_P (f)) PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0); /* When we are running in batch mode, there's no one to send a message, so we just signal the data is available and hope sys_select will be called soon and will read the data. */ #if 0 else if (FRAME_INITIAL_P (f) && noninteractive) ; #endif }