From 038c71f10c12a60698a801a95321e874e30e50d4 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Mon, 4 Mar 2002 08:12:53 +0000 Subject: 2002-03-04 Robert Collins * cygserver_shm.cc (client_request_shm::serve): Implement SHM_DETACH. * shm.cc (shmdt): Implement. --- winsup/cygserver/shm.cc | 20 ++++++++++++++++++++ winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/cygserver_shm.cc | 20 ++++++++++++++++++++ winsup/cygwin/shm.cc | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 76 insertions(+), 2 deletions(-) (limited to 'winsup') diff --git a/winsup/cygserver/shm.cc b/winsup/cygserver/shm.cc index de3e61e4e..50ca42e0e 100644 --- a/winsup/cygserver/shm.cc +++ b/winsup/cygserver/shm.cc @@ -290,6 +290,26 @@ client_request_shm::serve (transport_layer_base * conn, process_cache * cache) return; } + /* Someone detached */ + if (parameters.in.type == SHM_DETACH) + { + shmnode *tempnode = shm_head; + while (tempnode) + { + if (tempnode->shm_id == parameters.in.shm_id) + { + InterlockedDecrement (&tempnode->shmds->shm_nattch); + header.error_code = 0; + CloseHandle (token_handle); + return; + } + tempnode = tempnode->next; + } + header.error_code = EINVAL; + CloseHandle (token_handle); + return; + } + /* Someone wants the ID removed. */ if (parameters.in.type == SHM_DEL) { diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4db3d7fea..4b3436f61 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2002-03-04 Robert Collins + + * cygserver_shm.cc (client_request_shm::serve): Implement SHM_DETACH. + * shm.cc (shmdt): Implement. + 2002-03-04 Robert Collins * cygserver_shm.cc: Run indent. diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc index de3e61e4e..50ca42e0e 100755 --- a/winsup/cygwin/cygserver_shm.cc +++ b/winsup/cygwin/cygserver_shm.cc @@ -290,6 +290,26 @@ client_request_shm::serve (transport_layer_base * conn, process_cache * cache) return; } + /* Someone detached */ + if (parameters.in.type == SHM_DETACH) + { + shmnode *tempnode = shm_head; + while (tempnode) + { + if (tempnode->shm_id == parameters.in.shm_id) + { + InterlockedDecrement (&tempnode->shmds->shm_nattch); + header.error_code = 0; + CloseHandle (token_handle); + return; + } + tempnode = tempnode->next; + } + header.error_code = EINVAL; + CloseHandle (token_handle); + return; + } + /* Someone wants the ID removed. */ if (parameters.in.type == SHM_DEL) { diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc index 530539569..883c15074 100644 --- a/winsup/cygwin/shm.cc +++ b/winsup/cygwin/shm.cc @@ -305,8 +305,37 @@ shmdt (const void *shmaddr) /* this should be "rare" so a hefty search is ok. If this is common, then we * should alter the data structs to allow more optimisation */ - set_errno (ENOTSUP); - return -1; + shmnode *tempnode = shm_head; + _shmattach *attachnode; + while (tempnode) + { + // FIXME: Race potential + attachnode = tempnode->attachhead; + while (attachnode && attachnode->data != shmaddr) + attachnode = attachnode->next; + if (attachnode) + break; + tempnode = tempnode->next; + } + if (!tempnode) + { + // dt cannot be called by an app that hasn't alreadu at'd + set_errno (EINVAL); + return -1; + } + + UnmapViewOfFile (attachnode->data); + /* tell the daemon we have attached */ + client_request_shm *req = + new client_request_shm (SHM_DETACH, tempnode->shm_id); + int rc; + if ((rc = cygserver_request (req))) + { + debug_printf ("failed to tell deaemon that we have detached\n"); + } + delete req; + + return 0; } //FIXME: who is allowed to perform STAT? -- cgit v1.2.3