From 373a036f7bcdc9ef29f340752024c976b1695d34 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 6 Feb 2004 16:25:58 +0000 Subject: [PATCH] * bsd_mutex.cc (_msleep): Handle PCATCH using signal_arrived event. * client.cc: Include sigproc.h. * msg.cc (client_request_msg::serve): Accomodate third parameter to process::process. * sem.cc (client_request_sem::serve): Ditto. * shm.cc (client_request_shm::serve): Ditto. * process.cc (process::process): Duplicate signal_arrived into Cygserver process space. (process::~process): Close _signal_arrived handle. (process_cache::process): Add signal_arrived handling. * process.h (process::process): Add signal_arrived parameter. (process:signal_arrived): New read accessor. (process:_signal_arrived): New member. (process_cache::process): Add signal_arrived parameter. --- winsup/cygserver/ChangeLog | 17 +++++++++++++++++ winsup/cygserver/bsd_mutex.cc | 14 +++++++++++--- winsup/cygserver/client.cc | 2 ++ winsup/cygserver/msg.cc | 3 ++- winsup/cygserver/process.cc | 19 +++++++++++++++---- winsup/cygserver/process.h | 8 ++++++-- winsup/cygserver/sem.cc | 3 ++- winsup/cygserver/shm.cc | 3 ++- 8 files changed, 57 insertions(+), 12 deletions(-) diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog index e713ae104..838eee8d7 100644 --- a/winsup/cygserver/ChangeLog +++ b/winsup/cygserver/ChangeLog @@ -1,3 +1,20 @@ +2004-02-06 Corinna Vinschen + + * bsd_mutex.cc (_msleep): Handle PCATCH using signal_arrived event. + * client.cc: Include sigproc.h. + * msg.cc (client_request_msg::serve): Accomodate third parameter to + process::process. + * sem.cc (client_request_sem::serve): Ditto. + * shm.cc (client_request_shm::serve): Ditto. + * process.cc (process::process): Duplicate signal_arrived into + Cygserver process space. + (process::~process): Close _signal_arrived handle. + (process_cache::process): Add signal_arrived handling. + * process.h (process::process): Add signal_arrived parameter. + (process:signal_arrived): New read accessor. + (process:_signal_arrived): New member. + (process_cache::process): Add signal_arrived parameter. + 2004-01-16 Corinna Vinschen * process.h (cleanup_routine::~cleanup_routine): Make pure virtual diff --git a/winsup/cygserver/bsd_mutex.cc b/winsup/cygserver/bsd_mutex.cc index 9c7485b7f..af23f5668 100644 --- a/winsup/cygserver/bsd_mutex.cc +++ b/winsup/cygserver/bsd_mutex.cc @@ -188,9 +188,14 @@ _msleep (void *ident, struct mtx *mtx, int priority, if (mtx) mtx_unlock (mtx); int old_priority = set_priority (priority); - /* PCATCH can't be handled here. */ - HANDLE obj[3] = { evt, td->client->handle (), msleep_glob_evt }; - switch (WaitForMultipleObjects (3, obj, FALSE, timo ?: INFINITE)) + HANDLE obj[4] = { evt, td->client->handle (), msleep_glob_evt, td->client->signal_arrived () }; + /* PCATCH handling. If PCATCH is given and signal_arrived is a valid + handle, then it's used in the WaitFor call and EINTR is returned. */ + int obj_cnt = 3; + if ((priority & PCATCH) + && td->client->signal_arrived () != INVALID_HANDLE_VALUE) + obj_cnt = 4; + switch (WaitForMultipleObjects (obj_cnt, obj, FALSE, timo ?: INFINITE)) { case WAIT_OBJECT_0: /* wakeup() has been called. */ ret = 0; @@ -201,6 +206,9 @@ _msleep (void *ident, struct mtx *mtx, int priority, case WAIT_OBJECT_0 + 1: /* The dependent process has exited. */ ret = EIDRM; break; + case WAIT_OBJECT_0 + 3: /* Signal for calling process arrived. */ + ret = EINTR; + break; case WAIT_TIMEOUT: ret = EWOULDBLOCK; break; diff --git a/winsup/cygserver/client.cc b/winsup/cygserver/client.cc index d8f7ac55a..46451a99c 100644 --- a/winsup/cygserver/client.cc +++ b/winsup/cygserver/client.cc @@ -21,6 +21,8 @@ details. */ #include #include +#include "sigproc.h" + #include "cygerrno.h" #include "cygserver_msg.h" #include "cygserver_sem.h" diff --git a/winsup/cygserver/msg.cc b/winsup/cygserver/msg.cc index 52fdcd07e..fd5eaf5d5 100644 --- a/winsup/cygserver/msg.cc +++ b/winsup/cygserver/msg.cc @@ -55,7 +55,8 @@ client_request_msg::serve (transport_layer_base *const conn, return; } process *const client = cache->process (_parameters.in.ipcblk.cygpid, - _parameters.in.ipcblk.winpid); + _parameters.in.ipcblk.winpid, + _parameters.in.ipcblk.signal_arrived); if (!client) { error_code (EAGAIN); diff --git a/winsup/cygserver/process.cc b/winsup/cygserver/process.cc index 1cad23887..8f1ff5776 100644 --- a/winsup/cygserver/process.cc +++ b/winsup/cygserver/process.cc @@ -40,10 +40,11 @@ process_cleanup::process () /*****************************************************************************/ -process::process (const pid_t cygpid, const DWORD winpid) +process::process (const pid_t cygpid, const DWORD winpid, HANDLE signal_arrived) : _cygpid (cygpid), _winpid (winpid), _hProcess (NULL), + _signal_arrived (INVALID_HANDLE_VALUE), _cleaning_up (false), _exit_status (STILL_ACTIVE), _routines_head (NULL), @@ -60,13 +61,22 @@ process::process (const pid_t cygpid, const DWORD winpid) else debug_printf ("got handle %p for new cache process %d(%lu)", _hProcess, _cygpid, _winpid); + if (signal_arrived != INVALID_HANDLE_VALUE) + { + if (!DuplicateHandle (_hProcess, signal_arrived, + GetCurrentProcess (), &_signal_arrived, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + system_printf ("error getting signal_arrived to server (%lu)", + GetLastError ()); + } InitializeCriticalSection (&_access); } process::~process () { DeleteCriticalSection (&_access); - (void) CloseHandle (_hProcess); + CloseHandle (_signal_arrived); + CloseHandle (_hProcess); } /* No need to be thread-safe as this is only ever called by @@ -221,7 +231,8 @@ process_cache::~process_cache () * have been deleted once it has been unlocked. */ class process * -process_cache::process (const pid_t cygpid, const DWORD winpid) +process_cache::process (const pid_t cygpid, const DWORD winpid, + HANDLE signal_arrived) { /* TODO: make this more granular, so a search doesn't involve the * write lock. @@ -243,7 +254,7 @@ process_cache::process (const pid_t cygpid, const DWORD winpid) return NULL; } - entry = new class process (cygpid, winpid); + entry = new class process (cygpid, winpid, signal_arrived); if (!entry->is_active ()) { LeaveCriticalSection (&_cache_write_access); diff --git a/winsup/cygserver/process.h b/winsup/cygserver/process.h index c062ee193..90d7c94b5 100644 --- a/winsup/cygserver/process.h +++ b/winsup/cygserver/process.h @@ -71,12 +71,14 @@ class process friend class process_cleanup; public: - process (pid_t cygpid, DWORD winpid); + process (pid_t cygpid, DWORD winpid, + HANDLE signal_arrived = INVALID_HANDLE_VALUE); ~process (); pid_t cygpid () const { return _cygpid; } DWORD winpid () const { return _winpid; } HANDLE handle () const { return _hProcess; } + HANDLE signal_arrived () const { return _signal_arrived; } bool is_active () const { return _exit_status == STILL_ACTIVE; } @@ -90,6 +92,7 @@ private: const pid_t _cygpid; const DWORD _winpid; HANDLE _hProcess; + HANDLE _signal_arrived; long _cleaning_up; DWORD _exit_status; // Set in the constructor and in exit_code (). cleanup_routine *_routines_head; @@ -131,7 +134,8 @@ public: process_cache (unsigned int initial_workers); ~process_cache (); - class process *process (pid_t cygpid, DWORD winpid); + class process *process (pid_t cygpid, DWORD winpid, + HANDLE signal_arrived = INVALID_HANDLE_VALUE); bool running () const { return _queue.running (); } diff --git a/winsup/cygserver/sem.cc b/winsup/cygserver/sem.cc index dd48123d2..82ad3ded1 100644 --- a/winsup/cygserver/sem.cc +++ b/winsup/cygserver/sem.cc @@ -52,7 +52,8 @@ client_request_sem::serve (transport_layer_base *const conn, return; } process *const client = cache->process (_parameters.in.ipcblk.cygpid, - _parameters.in.ipcblk.winpid); + _parameters.in.ipcblk.winpid, + _parameters.in.ipcblk.signal_arrived); if (!client) { error_code (EAGAIN); diff --git a/winsup/cygserver/shm.cc b/winsup/cygserver/shm.cc index d8284cd44..48aec8a52 100644 --- a/winsup/cygserver/shm.cc +++ b/winsup/cygserver/shm.cc @@ -55,7 +55,8 @@ client_request_shm::serve (transport_layer_base *const conn, return; } process *const client = cache->process (_parameters.in.ipcblk.cygpid, - _parameters.in.ipcblk.winpid); + _parameters.in.ipcblk.winpid, + _parameters.in.ipcblk.signal_arrived); if (!client) { error_code (EAGAIN);