diff options
author | Conrad Scott <conrad.scott@dsl.pipex.com> | 2002-07-01 01:01:48 +0400 |
---|---|---|
committer | Conrad Scott <conrad.scott@dsl.pipex.com> | 2002-07-01 01:01:48 +0400 |
commit | c89053b489bdd8adfdc16a1a11fb5e82db4c1769 (patch) | |
tree | 3e82e67b79dec300e7934823993d79c7d6832824 | |
parent | 0eb401b32fc31015235f5e83cc26009862bb4de4 (diff) |
* woutsup.h: Remove all uses of the C++ new and delete operators
throughout cygserver until they are fully thread-safe.
(safe_new0): New macro to replace the C++ new operator.
(safe_new): Ditto.
(safe_delete): New macro to replace the C++ delete operator.
* cygserver_client.cc (client_request::handle_request): Replace
all uses of the C++ new and delete operators with the new macros
from "woutsup.h".
(client_request::make_request): Ditto.
* cygserver_process.cc (~process_cleanup): Ditto.
(process::cleanup): Ditto.
(process_cache::process): Ditto.
(process_cache::check_and_remove_process): Ditto.
* cygserver_shm.cc (server_shmmgr::new_segment): Ditto.
(server_shmmgr::delete_segment): Ditto.
* cygserver_transport.cc (create_server_transport): Ditto.
* cygserver_transport_pipes.cc
(transport_layer_pipes::accept): Ditto.
* cygserver_transport_sockets.cc
(transport_layer_sockets::accept): Ditto.
* threaded_queue.cc (~threaded_queue): Ditto.
(threaded_queue::worker_loop): Ditto.
(threaded_queue::stop): Replace sleep(3) with win32 Sleep.
* cygserver.cc (~server_request): Replace all uses of the C++ new
and delete operators with the new macros from "woutsup.h".
(server_submission_loop::request_loop): Ditto.
(main): Ditto. Replace sleep(3) with win32 Sleep. Replace
iostreams with FILEs.
(print_usage): Replace iostreams with FILEs.
(print_version): Ditto.
-rw-r--r-- | winsup/cygserver/threaded_queue.cc | 6 | ||||
-rw-r--r-- | winsup/cygserver/woutsup.h | 34 | ||||
-rw-r--r-- | winsup/cygwin/ChangeLog | 33 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver.cc | 56 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_client.cc | 32 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_process.cc | 11 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_shm.cc | 4 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_transport.cc | 17 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_transport_pipes.cc | 2 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_transport_sockets.cc | 2 | ||||
-rwxr-xr-x | winsup/cygwin/threaded_queue.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/woutsup.h | 34 |
12 files changed, 172 insertions, 65 deletions
diff --git a/winsup/cygserver/threaded_queue.cc b/winsup/cygserver/threaded_queue.cc index e3da7f747..ee7a36e3f 100644 --- a/winsup/cygserver/threaded_queue.cc +++ b/winsup/cygserver/threaded_queue.cc @@ -73,7 +73,7 @@ threaded_queue::~threaded_queue () { queue_request *const ptr = reqptr; reqptr = reqptr->_next; - delete ptr; + safe_delete (queue_request, ptr); } DeleteCriticalSection (&_queue_lock); @@ -146,7 +146,7 @@ threaded_queue::stop () debug_printf (("waiting for worker threads to terminate: " "%lu still running"), _workers_count); - sleep (1); + Sleep (1000); } debug_printf ("all worker threads have terminated"); } @@ -265,7 +265,7 @@ threaded_queue::worker_loop () assert (reqptr); reqptr->process (); - delete reqptr; + safe_delete (queue_request, reqptr); } } diff --git a/winsup/cygserver/woutsup.h b/winsup/cygserver/woutsup.h index 9c153793c..e93a2586c 100644 --- a/winsup/cygserver/woutsup.h +++ b/winsup/cygserver/woutsup.h @@ -106,3 +106,37 @@ extern "C" void __cygserver__printf (const char *, const char *, ...); #define malloc_printf __noop_printf #define thread_printf __noop_printf #endif + +/*****************************************************************************/ + +/* Temporary hack to get around the thread-unsafe new/delete in cygwin + * gcc 2.95.3. This should all be binned at the first opportunity, + * e.g. gcc 3.1 or sooner. + * + * The trick here is to do contruction via malloc(3) and then the + * placement new operator, and destruction via an explicit call to the + * destructor and then free(3). + */ + +#include <new.h> +#include <stdlib.h> + +#define safe_new0(T) (new (malloc (sizeof (T))) T) + +#ifdef NEW_MACRO_VARARGS + +#define safe_new(T, ...) \ + (new (malloc (sizeof (T))) T (__VA_ARGS__)) + +#else /* !NEW_MACRO_VARARGS */ + +#define safe_new(T, args...) \ + (new (malloc (sizeof (T))) T (## args)) + +#endif /* !NEW_MACRO_VARARGS */ + +#define safe_delete(T, O) \ +{ \ + (O)->~ ## T (); \ + free (O); \ +} diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0ee7ca67c..726647f38 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,38 @@ 2002-06-30 Conrad Scott <conrad.scott@dsl.pipex.com> + * woutsup.h: Remove all uses of the C++ new and delete operators + throughout cygserver until they are fully thread-safe. + (safe_new0): New macro to replace the C++ new operator. + (safe_new): Ditto. + (safe_delete): New macro to replace the C++ delete operator. + * cygserver_client.cc (client_request::handle_request): Replace + all uses of the C++ new and delete operators with the new macros + from "woutsup.h". + (client_request::make_request): Ditto. + * cygserver_process.cc (~process_cleanup): Ditto. + (process::cleanup): Ditto. + (process_cache::process): Ditto. + (process_cache::check_and_remove_process): Ditto. + * cygserver_shm.cc (server_shmmgr::new_segment): Ditto. + (server_shmmgr::delete_segment): Ditto. + * cygserver_transport.cc (create_server_transport): Ditto. + * cygserver_transport_pipes.cc + (transport_layer_pipes::accept): Ditto. + * cygserver_transport_sockets.cc + (transport_layer_sockets::accept): Ditto. + * threaded_queue.cc (~threaded_queue): Ditto. + (threaded_queue::worker_loop): Ditto. + (threaded_queue::stop): Replace sleep(3) with win32 Sleep. + * cygserver.cc (~server_request): Replace all uses of the C++ new + and delete operators with the new macros from "woutsup.h". + (server_submission_loop::request_loop): Ditto. + (main): Ditto. Replace sleep(3) with win32 Sleep. Replace + iostreams with FILEs. + (print_usage): Replace iostreams with FILEs. + (print_version): Ditto. + +2002-06-30 Conrad Scott <conrad.scott@dsl.pipex.com> + * cygserver_transport_sockets.cc (transport_layer_sockets::accept): Rename local variable `accept_fd' to avoid shadowing the `fd' field. diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc index 9baf90303..24a05d61d 100755 --- a/winsup/cygwin/cygserver.cc +++ b/winsup/cygwin/cygserver.cc @@ -24,8 +24,6 @@ details. */ #include <string.h> #include <unistd.h> -#include <ostream.h> - #include "cygerrno.h" #include "cygwin_version.h" @@ -78,14 +76,14 @@ getfunc (char *in_dst, const char *func) * Support function for the XXX_printf() macros in "woutsup.h". */ extern "C" void -__cygserver__printf (const char * const function, const char * const fmt, ...) +__cygserver__printf (const char *const function, const char *const fmt, ...) { const DWORD lasterror = GetLastError (); const int lasterrno = errno; va_list ap; - char * const buf = (char *) alloca(BUFSIZ); + char *const buf = (char *) alloca(BUFSIZ); assert (buf); @@ -172,7 +170,7 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process, HANDLE from_process_token, DWORD access, HANDLE from_handle, - HANDLE* to_handle_ptr, BOOL bInheritHandle = FALSE) + HANDLE *to_handle_ptr, BOOL bInheritHandle = FALSE) { HANDLE local_handle = NULL; int ret_val = EACCES; @@ -404,7 +402,7 @@ public: virtual ~server_request() { - delete _conn; + safe_delete (transport_layer_base, _conn); } virtual void process () @@ -457,7 +455,7 @@ server_submission_loop::request_loop () return; } if (conn) - _queue->add (new server_request (conn, _cache)); + _queue->add (safe_new (server_request, conn, _cache)); } } @@ -487,7 +485,7 @@ client_request_shutdown::serve (transport_layer_base *, process_cache *) } static void -handle_signal (int signal) +handle_signal (const int signum) { /* any signal makes us die :} */ @@ -499,13 +497,12 @@ handle_signal (int signal) */ static void -print_usage (const char * const pgm) +print_usage (const char *const pgm) { - cout << "Usage: " << pgm << "[OPTIONS]\n" - << ( " -h, --help output usage information and exit\n" - " -s, --shutdown shutdown the current instance of the daemon\n" - " -v, --version output version information and exit\n" ) - << flush; + printf ("Usage: %s [OPTIONS]\n", pgm); + printf (" -h, --help output usage information and exit\n"); + printf (" -s, --shutdown shutdown the current instance of the daemon\n"); + printf (" -v, --version output version information and exit\n"); } /* @@ -513,11 +510,11 @@ print_usage (const char * const pgm) */ static void -print_version (const char * const pgm) +print_version (const char *const pgm) { - char * vn = NULL; + char *vn = NULL; - const char * colon = strchr (version, ':'); + const char *const colon = strchr (version, ':'); if (!colon) { @@ -527,7 +524,7 @@ print_version (const char * const pgm) { vn = strdup (colon + 2); // Skip ": " - char * const spc = strchr (vn, ' '); + char *const spc = strchr (vn, ' '); if (spc) *spc = '\0'; @@ -548,10 +545,10 @@ print_version (const char * const pgm) cygwin_version.mount_registry, cygwin_version.dll_build_date); - cout << pgm << " (cygwin) " << vn << endl - << "API version " << buf << endl - << "Copyright 2001, 2002 Red Hat, Inc." << endl - << "Compiled on " __DATE__ << endl; + printf ("%s (cygwin) %s\n", pgm, vn); + printf ("API version %s\n", buf); + printf ("Copyright 2001, 2002 Red Hat, Inc.\n"); + printf ("Compiled on %s\n", __DATE__); free (vn); } @@ -574,7 +571,7 @@ main (const int argc, char *argv[]) bool shutdown = false; - const char * pgm = NULL; + const char *pgm = NULL; if (!(pgm = strrchr (*argv, '\\')) && !(pgm = strrchr (*argv, '/'))) pgm = *argv; @@ -603,13 +600,13 @@ main (const int argc, char *argv[]) return 0; case '?': - cerr << "Try `" << pgm << " --help' for more information." << endl; + fprintf (stderr, "Try `%s --help' for more information.\n", pgm); exit (1); } if (optind != argc) { - cerr << pgm << ": too many arguments" << endl; + fprintf (stderr, "%s: too many arguments\n", pgm); exit (1); } @@ -622,8 +619,8 @@ main (const int argc, char *argv[]) if (req.make_request () == -1 || req.error_code ()) { - cout << pgm << ": shutdown request failed: " - << strerror(errno) << endl; + fprintf (stderr, "%s: shutdown request failed: %s\n", + pgm, strerror (errno)); exit (1); } @@ -639,7 +636,6 @@ main (const int argc, char *argv[]) exit (1); } - print_version (pgm); setbuf (stdout, NULL); printf ("daemon starting up"); @@ -684,12 +680,12 @@ main (const int argc, char *argv[]) -- if signal event then retrigger it */ while (!shutdown_server && request_queue.running () && cache.running ()) - sleep (1); + Sleep (1000); printf ("\nShutdown request received - new requests will be denied\n"); request_queue.stop (); printf ("All pending requests processed\n"); - delete transport; + safe_delete (transport_layer_base, transport); printf ("No longer accepting requests - cygwin will operate in daemonless mode\n"); cache.stop (); printf ("All outstanding process-cache activities completed\n"); diff --git a/winsup/cygwin/cygserver_client.cc b/winsup/cygwin/cygserver_client.cc index c63a61a84..f7f098a95 100755 --- a/winsup/cygwin/cygserver_client.cc +++ b/winsup/cygwin/cygserver_client.cc @@ -17,8 +17,6 @@ details. */ #include "winsup.h" #endif -#include <sys/socket.h> - #include <assert.h> #include <errno.h> #include <stdio.h> @@ -281,17 +279,17 @@ client_request::handle_request (transport_layer_base *const conn, switch (header.request_code) { - case CYGSERVER_REQUEST_GET_VERSION: - req = new client_request_get_version (); + case CYGSERVER_REQUEST_GET_VERSION: + req = safe_new0 (client_request_get_version); break; - case CYGSERVER_REQUEST_SHUTDOWN: - req = new client_request_shutdown (); + case CYGSERVER_REQUEST_SHUTDOWN: + req = safe_new0 (client_request_shutdown); break; - case CYGSERVER_REQUEST_ATTACH_TTY: - req = new client_request_attach_tty (); + case CYGSERVER_REQUEST_ATTACH_TTY: + req = safe_new0 (client_request_attach_tty); break; - case CYGSERVER_REQUEST_SHM: - req = new client_request_shm (); + case CYGSERVER_REQUEST_SHM: + req = safe_new0 (client_request_shm); break; default: syscall_printf ("unknown request code %d received: request ignored", @@ -304,7 +302,7 @@ client_request::handle_request (transport_layer_base *const conn, req->msglen (header.msglen); req->handle (conn, cache); - delete (req); + safe_delete (client_request, req); printf ("."); } @@ -357,7 +355,11 @@ client_request::make_request () error_code (errno); else error_code (ENOSYS); +#ifdef safe_delete + safe_delete (transport_layer_base, transport); +#else delete transport; +#endif return -1; } @@ -365,7 +367,11 @@ client_request::make_request () send (transport); +#ifdef safe_delete + safe_delete (transport_layer_base, transport); +#else delete transport; +#endif return 0; } @@ -501,13 +507,13 @@ check_cygserver_available (const bool check_version_too) syscall_printf ("process will continue without cygserver support"); return false; } - + if (check_version_too && !req.check_version ()) { return false; } - return true; + return true; } /* diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc index 3859c4377..2760dd013 100755 --- a/winsup/cygwin/cygserver_process.cc +++ b/winsup/cygwin/cygserver_process.cc @@ -16,7 +16,6 @@ details. */ #include <assert.h> #include <errno.h> -#include <pthread.h> #include <stdlib.h> #include "cygerrno.h" @@ -31,7 +30,7 @@ details. */ process_cleanup::~process_cleanup () { - delete _process; + safe_delete (process, _process); } void @@ -137,7 +136,7 @@ process::cleanup () cleanup_routine *const ptr = entry; entry = entry->_next; ptr->cleanup (_winpid); - delete ptr; + safe_delete (cleanup_routine, ptr); } } @@ -216,11 +215,11 @@ process_cache::process (const DWORD winpid) return NULL; } - entry = new class process (winpid); + entry = safe_new (class process, winpid); if (entry->_exit_status != STILL_ACTIVE) { LeaveCriticalSection (&_cache_write_access); - delete entry; + safe_delete (process, entry); set_errno (ESRCH); return NULL; } @@ -375,7 +374,7 @@ process_cache::check_and_remove_process (const size_t index) LeaveCriticalSection (&_cache_write_access); /* Schedule any cleanup tasks for this process. */ - _queue.add (new process_cleanup (process)); + _queue.add (safe_new (process_cleanup, process)); } class process * diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc index 2df6522ed..51c3d3b85 100755 --- a/winsup/cygwin/cygserver_shm.cc +++ b/winsup/cygwin/cygserver_shm.cc @@ -447,7 +447,7 @@ server_shmmgr::new_segment (const key_t key, const HANDLE hFileMap) previous = segptr; } - segment_t *const segptr = new segment_t (key, shmid, hFileMap); + segment_t *const segptr = safe_new (segment_t, key, shmid, hFileMap); assert (segptr); @@ -501,7 +501,7 @@ server_shmmgr::delete_segment (segment_t *const segptr) assert (_shmid_cnt > 0); _shmid_cnt -= 1; - delete segptr; + safe_delete (segment_t, segptr); } /*---------------------------------------------------------------------------* diff --git a/winsup/cygwin/cygserver_transport.cc b/winsup/cygwin/cygserver_transport.cc index 8d0d164fe..641f54456 100755 --- a/winsup/cygwin/cygserver_transport.cc +++ b/winsup/cygwin/cygserver_transport.cc @@ -24,15 +24,20 @@ details. */ #include "cygwin/cygserver_transport_sockets.h" /* The factory */ -class transport_layer_base *create_server_transport() +transport_layer_base * +create_server_transport () { - transport_layer_base *temp; - /* currently there is only the base class! */ +#ifdef safe_new0 if (wincap.is_winnt ()) - temp = new transport_layer_pipes (); + return safe_new0 (transport_layer_pipes); else - temp = new transport_layer_sockets (); - return temp; + return safe_new0 (transport_layer_pipes); +#else + if (wincap.is_winnt ()) + return new transport_layer_pipes; + else + return new transport_layer_pipes; +#endif } #ifndef __INSIDE_CYGWIN__ diff --git a/winsup/cygwin/cygserver_transport_pipes.cc b/winsup/cygwin/cygserver_transport_pipes.cc index 26ed50053..a539a13b6 100755 --- a/winsup/cygwin/cygserver_transport_pipes.cc +++ b/winsup/cygwin/cygserver_transport_pipes.cc @@ -163,7 +163,7 @@ transport_layer_pipes::accept (bool * const recoverable) return NULL; } - return new transport_layer_pipes (accept_pipe); + return safe_new (transport_layer_pipes, accept_pipe); } #endif /* !__INSIDE_CYGWIN__ */ diff --git a/winsup/cygwin/cygserver_transport_sockets.cc b/winsup/cygwin/cygserver_transport_sockets.cc index 78fceb1b5..060382594 100755 --- a/winsup/cygwin/cygserver_transport_sockets.cc +++ b/winsup/cygwin/cygserver_transport_sockets.cc @@ -112,7 +112,7 @@ transport_layer_sockets::accept (bool * const recoverable) return NULL; } - return new transport_layer_sockets (accept_fd); + return safe_new (transport_layer_sockets, accept_fd); } #endif /* !__INSIDE_CYGWIN__ */ diff --git a/winsup/cygwin/threaded_queue.cc b/winsup/cygwin/threaded_queue.cc index e3da7f747..ee7a36e3f 100755 --- a/winsup/cygwin/threaded_queue.cc +++ b/winsup/cygwin/threaded_queue.cc @@ -73,7 +73,7 @@ threaded_queue::~threaded_queue () { queue_request *const ptr = reqptr; reqptr = reqptr->_next; - delete ptr; + safe_delete (queue_request, ptr); } DeleteCriticalSection (&_queue_lock); @@ -146,7 +146,7 @@ threaded_queue::stop () debug_printf (("waiting for worker threads to terminate: " "%lu still running"), _workers_count); - sleep (1); + Sleep (1000); } debug_printf ("all worker threads have terminated"); } @@ -265,7 +265,7 @@ threaded_queue::worker_loop () assert (reqptr); reqptr->process (); - delete reqptr; + safe_delete (queue_request, reqptr); } } diff --git a/winsup/cygwin/woutsup.h b/winsup/cygwin/woutsup.h index 9c153793c..e93a2586c 100644 --- a/winsup/cygwin/woutsup.h +++ b/winsup/cygwin/woutsup.h @@ -106,3 +106,37 @@ extern "C" void __cygserver__printf (const char *, const char *, ...); #define malloc_printf __noop_printf #define thread_printf __noop_printf #endif + +/*****************************************************************************/ + +/* Temporary hack to get around the thread-unsafe new/delete in cygwin + * gcc 2.95.3. This should all be binned at the first opportunity, + * e.g. gcc 3.1 or sooner. + * + * The trick here is to do contruction via malloc(3) and then the + * placement new operator, and destruction via an explicit call to the + * destructor and then free(3). + */ + +#include <new.h> +#include <stdlib.h> + +#define safe_new0(T) (new (malloc (sizeof (T))) T) + +#ifdef NEW_MACRO_VARARGS + +#define safe_new(T, ...) \ + (new (malloc (sizeof (T))) T (__VA_ARGS__)) + +#else /* !NEW_MACRO_VARARGS */ + +#define safe_new(T, args...) \ + (new (malloc (sizeof (T))) T (## args)) + +#endif /* !NEW_MACRO_VARARGS */ + +#define safe_delete(T, O) \ +{ \ + (O)->~ ## T (); \ + free (O); \ +} |