Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Scott <conrad.scott@dsl.pipex.com>2002-07-01 01:01:48 +0400
committerConrad Scott <conrad.scott@dsl.pipex.com>2002-07-01 01:01:48 +0400
commitc89053b489bdd8adfdc16a1a11fb5e82db4c1769 (patch)
tree3e82e67b79dec300e7934823993d79c7d6832824
parent0eb401b32fc31015235f5e83cc26009862bb4de4 (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.cc6
-rw-r--r--winsup/cygserver/woutsup.h34
-rw-r--r--winsup/cygwin/ChangeLog33
-rwxr-xr-xwinsup/cygwin/cygserver.cc56
-rwxr-xr-xwinsup/cygwin/cygserver_client.cc32
-rwxr-xr-xwinsup/cygwin/cygserver_process.cc11
-rwxr-xr-xwinsup/cygwin/cygserver_shm.cc4
-rwxr-xr-xwinsup/cygwin/cygserver_transport.cc17
-rwxr-xr-xwinsup/cygwin/cygserver_transport_pipes.cc2
-rwxr-xr-xwinsup/cygwin/cygserver_transport_sockets.cc2
-rwxr-xr-xwinsup/cygwin/threaded_queue.cc6
-rw-r--r--winsup/cygwin/woutsup.h34
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); \
+}