diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-05-10 20:56:07 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-05-10 20:56:07 +0000 |
commit | 13505ca8fce1c22a7f124314a07b4ecbb62bee22 (patch) | |
tree | b106d7bea11ff8519a23d3955c7d4faa20c75f3c /winsup/cygwin/select.cc | |
parent | a586e5b6ae64fc46496249b2fd35bec613e3a724 (diff) | |
download | cygnal-13505ca8fce1c22a7f124314a07b4ecbb62bee22.tar.gz cygnal-13505ca8fce1c22a7f124314a07b4ecbb62bee22.tar.bz2 cygnal-13505ca8fce1c22a7f124314a07b4ecbb62bee22.zip |
* Makefile.in (DLL_OFILES): Add fhandler_mailslot.o.
* devices.h (FH_KMSG): Define new device.
* devices.in: Add "/dev/kmsg" entry.
* devices.cc: Regenerate.
* dtable.cc (build_fh_pc): Handle case FH_KMSG.
* fhandler.h (class fhandler_mailslot): New class.
(class select_stuff): Add device_specific_mailslot pointer.
* fhandler_mailslot.cc: New file.
* select.cc (peek_mailslot): New function.
(verify_mailslot): Ditto.
(struct mailslotinf): New stuct to handle select on mailslots.
(thread_mailslot): New function.
(start_thread_mailslot): Ditto.
(mailslot_cleanup): Ditto.
(fhandler_mailslot::select_read): New method.
* syslog.cc (klog_guard): New muto.
(dev_kmsg): Local mailslot for kernel message device.
(vklog): New function.
(klog): Ditto.
* winsup.h (vklog): Declare.
(klog): Ditto.
* include/sys/syslog.h: Define _PATH_KLOG.
Diffstat (limited to 'winsup/cygwin/select.cc')
-rw-r--r-- | winsup/cygwin/select.cc | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 9a6ccf2ea..1acf80eb2 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1591,3 +1591,123 @@ fhandler_windows::select_except (select_record *s) s->windows_handle = true; return s; } + +static int +peek_mailslot (select_record *me, bool) +{ + HANDLE h; + set_handle_or_return_if_not_open (h, me); + + if (me->read_selected && me->read_ready) + return 1; + DWORD msgcnt = 0; + if (!GetMailslotInfo (h, NULL, NULL, &msgcnt, NULL)) + { + select_printf ("mailslot %d(%p) error %E", me->fd, h); + return 1; + } + if (msgcnt > 0) + { + me->read_ready = true; + select_printf ("mailslot %d(%p) ready", me->fd, h); + return 1; + } + select_printf ("mailslot %d(%p) not ready", me->fd, h); + return 0; +} + +static int +verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds, + fd_set *efds) +{ + return peek_mailslot (me, true); +} + +static int start_thread_mailslot (select_record *me, select_stuff *stuff); + +struct mailslotinf + { + cygthread *thread; + bool stop_thread_mailslot; + select_record *start; + }; + +static DWORD WINAPI +thread_mailslot (void *arg) +{ + mailslotinf *mi = (mailslotinf *) arg; + bool gotone = false; + + for (;;) + { + select_record *s = mi->start; + while ((s = s->next)) + if (s->startup == start_thread_mailslot) + { + if (peek_mailslot (s, true)) + gotone = true; + if (mi->stop_thread_mailslot) + { + select_printf ("stopping"); + goto out; + } + } + /* Paranoid check */ + if (mi->stop_thread_mailslot) + { + select_printf ("stopping from outer loop"); + break; + } + if (gotone) + break; + Sleep (10); + } +out: + return 0; +} + +static int +start_thread_mailslot (select_record *me, select_stuff *stuff) +{ + if (stuff->device_specific_mailslot) + { + me->h = *((mailslotinf *) stuff->device_specific_mailslot)->thread; + return 1; + } + mailslotinf *mi = new mailslotinf; + mi->start = &stuff->start; + mi->stop_thread_mailslot = false; + mi->thread = new cygthread (thread_mailslot, (LPVOID) mi, "select_mailslot"); + me->h = *mi->thread; + if (!me->h) + return 0; + stuff->device_specific_mailslot = (void *) mi; + return 1; +} + +static void +mailslot_cleanup (select_record *, select_stuff *stuff) +{ + mailslotinf *mi = (mailslotinf *) stuff->device_specific_mailslot; + if (mi && mi->thread) + { + mi->stop_thread_mailslot = true; + mi->thread->detach (); + delete mi; + stuff->device_specific_mailslot = NULL; + } +} + +select_record * +fhandler_mailslot::select_read (select_record *s) +{ + if (!s) + s = new select_record; + s->startup = start_thread_mailslot; + s->peek = peek_mailslot; + s->verify = verify_mailslot; + s->cleanup = mailslot_cleanup; + s->read_selected = true; + s->read_ready = false; + return s; +} |