diff options
Diffstat (limited to 'winsup/cygwin/cygserver_process.cc')
-rwxr-xr-x | winsup/cygwin/cygserver_process.cc | 388 |
1 files changed, 0 insertions, 388 deletions
diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc deleted file mode 100755 index dd13f37fb..000000000 --- a/winsup/cygwin/cygserver_process.cc +++ /dev/null @@ -1,388 +0,0 @@ -/* cygserver_process.cc - - Copyright 2001, 2002 Red Hat Inc. - - Written by Robert Collins <rbtcollins@hotmail.com> - - This file is part of Cygwin. - - This software is a copyrighted work licensed under the terms of the - Cygwin license. Please consult the file "CYGWIN_LICENSE" for - details. */ - -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <windows.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include "wincap.h" -#include <pthread.h> -#include <threaded_queue.h> -#include <cygwin/cygserver_process.h> - -#define debug_printf if (DEBUG) printf -#define DEBUG 1 - -/* the cache structures and classes are designed for one cache per server process. - * To make multiple process caches, a redesign will be needed - */ - -/* process cache */ -process_cache::process_cache (unsigned int num_initial_workers): -head (NULL) -{ - /* there can only be one */ - InitializeCriticalSection (&cache_write_access); - if ((cache_add_trigger = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL) - { - printf ("Failed to create cache add trigger (%lu), terminating\n", - GetLastError ()); - exit (1); - } - initial_workers = num_initial_workers; -} - -process_cache::~process_cache () -{ -} - -class process * -process_cache::process (long pid) -{ - class process *entry = head; - /* TODO: make this more granular, so a search doesn't involve the write lock */ - EnterCriticalSection (&cache_write_access); - if (!entry) - { - entry = new class process (pid); - entry->next = - (class process *) InterlockedExchangePointer (&head, entry); - PulseEvent (cache_add_trigger); - } - else - { - while (entry->winpid != pid && entry->next) - entry = entry->next; - if (entry->winpid != pid) - { - class process *new_entry = new class process (pid); - new_entry->next = - (class process *) InterlockedExchangePointer (&entry->next, - new_entry); - entry = new_entry; - PulseEvent (cache_add_trigger); - } - } - LeaveCriticalSection (&cache_write_access); - return entry; -} - -static DWORD WINAPI -request_loop (LPVOID LpParam) -{ - class process_process_param *params = (process_process_param *) LpParam; - return params->request_loop (); -} - -void -process_cache::process_requests () -{ - class process_process_param *params = new process_process_param; - threaded_queue::process_requests (params, request_loop); -} - -void -process_cache::add_task (class process * theprocess) -{ - /* safe to not "Try" because workers don't hog this, they wait on the event - */ - /* every derived ::add must enter the section! */ - EnterCriticalSection (&queuelock); - queue_request *listrequest = new process_cleanup (theprocess); - threaded_queue::add (listrequest); - LeaveCriticalSection (&queuelock); -} - -/* NOT fully MT SAFE: must be called by only one thread in a program */ -void -process_cache::remove_process (class process *theprocess) -{ - class process *entry = head; - /* unlink */ - EnterCriticalSection (&cache_write_access); - if (entry == theprocess) - { - entry = (class process *) InterlockedExchangePointer (&head, theprocess->next); - if (entry != theprocess) - { - printf ("Bug encountered, process cache corrupted\n"); - exit (1); - } - } - else - { - while (entry->next && entry->next != theprocess) - entry = entry->next; - class process *temp = (class process *) InterlockedExchangePointer (&entry->next, theprocess->next); - if (temp != theprocess) - { - printf ("Bug encountered, process cache corrupted\n"); - exit (1); - } - } - LeaveCriticalSection (&cache_write_access); - /* Process any cleanup tasks */ - add_task (theprocess); -} - -/* copy <= max_copy HANDLEs to dest[], starting at an offset into _our list_ of - * begin_at. (Ie begin_at = 5, the first copied handle is still written to dest[0] - * NOTE: Thread safe, but not thread guaranteed - a newly added process may be missed. - * Who cares - It'll get caught the next time. - */ -int -process_cache::handle_snapshot (HANDLE * hdest, class process ** edest, - ssize_t max_copy, int begin_at) -{ - /* TODO:? grab a delete-lock, to prevent deletes during this process ? */ - class process *entry = head; - int count = begin_at; - /* skip begin_at entries */ - while (entry && count) - { - if (entry->exit_code () == STILL_ACTIVE) - count--; - entry = entry->next; - } - /* hit the end of the list within begin_at entries */ - if (count) - return 0; - HANDLE *hto = hdest; - class process **eto = edest; - while (entry && count < max_copy) - { - /* hack */ - if (entry->exit_code () == STILL_ACTIVE) - { - *hto = entry->handle (); - *eto = entry; - count++; - hto++; - eto++; - } - entry = entry->next; - } - return count; -} - -/* process's */ -/* global process crit section */ -static CRITICAL_SECTION process_access; -static pthread_once_t process_init; - -void -do_process_init (void) -{ - InitializeCriticalSection (&process_access); - /* we don't have a cache shutdown capability today */ -} - -process::process (long pid): -winpid (pid), next (NULL), cleaning_up (0), head (NULL), _exit_status (STILL_ACTIVE) -{ - pthread_once (&process_init, do_process_init); - EnterCriticalSection (&process_access); - thehandle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); - if (!thehandle) - { - printf ("unable to obtain handle for new cache process %ld\n", pid); - thehandle = INVALID_HANDLE_VALUE; - } - debug_printf ("Got handle %p for new cache process %ld\n", thehandle, pid); - InitializeCriticalSection (&access); - LeaveCriticalSection (&process_access); -} - -process::~process () -{ - DeleteCriticalSection (&access); -} - -HANDLE -process::handle () -{ -// DWORD exitstate = exit_code (); -// if (exitstate == STILL_ACTIVE) - return thehandle; - - /* FIXME: call the cleanup list ? */ - -// CloseHandle (thehandle); -// debug_printf ("Process id %ld has terminated, attempting to open a new handle\n", -// winpid); -// thehandle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, winpid); -// debug_printf ("Got handle %p when refreshing cache process %ld\n", thehandle, winpid); -// /* FIXME: what if OpenProcess fails ? */ -// if (thehandle) -// { -// _exit_status = STILL_ACTIVE; -// exit_code (); -// } -// else -// thehandle = INVALID_HANDLE_VALUE; -// return thehandle; -} - -DWORD process::exit_code () -{ - if (_exit_status != STILL_ACTIVE) - return _exit_status; - bool - err = GetExitCodeProcess (thehandle, &_exit_status); - if (!err) - { - debug_printf ("Failed to retrieve exit code (%ld)\n", GetLastError ()); - thehandle = INVALID_HANDLE_VALUE; - return _exit_status; - } - else if (_exit_status == STILL_ACTIVE) - return _exit_status; - /* add new cleanup task etc etc ? */ - return _exit_status; -} - -/* this is single threaded. It's called after the process is removed from the cache, - * but inserts may be attemped by worker threads that have a pointer to it */ -void -process::cleanup () -{ - /* Serialize this */ - EnterCriticalSection (&access); - InterlockedIncrement (&(long)cleaning_up); - class cleanup_routine *entry = head; - while (entry) - { - class cleanup_routine *temp; - entry->cleanup (winpid); - temp = entry->next; - delete entry; - entry = temp; - } - LeaveCriticalSection (&access); -} - -bool -process::add_cleanup_routine (class cleanup_routine *new_cleanup) -{ - if (cleaning_up) - return false; - EnterCriticalSection (&access); - /* check that we didn't block with ::cleanup () - * This rigmarole is to get around win9x's glaring missing TryEnterCriticalSection call - * which would be a whole lot easier - */ - if (cleaning_up) - { - LeaveCriticalSection (&access); - return false; - } - new_cleanup->next = head; - head = new_cleanup; - LeaveCriticalSection (&access); - return true; -} - -/* process_cleanup */ -void -process_cleanup::process () -{ - theprocess->cleanup (); - delete theprocess; -} - -/* process_process_param */ -DWORD -process_process_param::request_loop () -{ - process_cache *cache = (process_cache *) queue; - /* always malloc one, so there is no special case in the loop */ - ssize_t HandlesSize = 2; - HANDLE *Handles = (HANDLE *) malloc (sizeof (HANDLE) * HandlesSize); - process **Entries = (process **) malloc (sizeof (LPVOID) * HandlesSize); - /* TODO: put [1] at the end as it will also get done if a process dies? */ - Handles[0] = interrupt; - Handles[1] = cache->cache_add_trigger; - while (cache->active && !shutdown) - { - int copied; - copied = -1; - int offset; - offset = 1; - int count; - count = 2; - while ((copied == HandlesSize - 2 - offset) || copied < 0) - { - /* we need more storage to cope with all the HANDLES */ - if (copied == HandlesSize - 2 - offset) - { - HANDLE *temp = (HANDLE *) realloc (Handles, - sizeof (HANDLE) * - HandlesSize + 10); - if (!temp) - { - printf - ("cannot allocate more storage for the handle array!\n"); - exit (1); - } - Handles = temp; - process **ptemp = (process **) realloc (Entries, - sizeof (LPVOID) * - HandlesSize + 10); - if (!ptemp) - { - printf - ("cannot allocate more storage for the handle array!\n"); - exit (1); - } - Entries = ptemp; - HandlesSize += 10; - } - offset += copied; - copied = - cache->handle_snapshot (&Handles[2], &Entries[2], - HandlesSize - 2 - offset, offset); - count += copied; - } - debug_printf ("waiting on %u objects\n", count); - DWORD rc = WaitForMultipleObjects (count, Handles, FALSE, INFINITE); - if (rc == WAIT_FAILED) - { - printf ("Could not wait on the process handles (%ld)!\n", - GetLastError ()); - exit (1); - } - int objindex = rc - WAIT_OBJECT_0; - if (objindex > 1 && objindex < count) - { - debug_printf ("Process %ld has left the building\n", - Entries[objindex]->winpid); - /* fire off the termination routines */ - cache->remove_process (Entries[objindex]); - } - else if (objindex >= 0 && objindex < 2) - { - /* 0 is shutdown - do nothing */ - /* 1 is a cache add event - just rebuild the object list */ - } - else - { - printf - ("unexpected return code from WaitForMultiple objects in process_process_param::request_loop\n"); - } - } - running = false; - return 0; -} |