diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-04-16 10:02:20 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-04-16 10:02:20 +0000 |
commit | 00218192218c00253416e7aa38351a90a6c98d64 (patch) | |
tree | 933307298b561d15f4caf710c7c7e853431338a2 | |
parent | 3959e0dd3988c75fd3d5e1594d3372b5c342e440 (diff) | |
download | ATCD-00218192218c00253416e7aa38351a90a6c98d64.tar.gz |
*** empty log message ***
-rw-r--r-- | ChangeLog-97a | 104 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | ace/Connector.cpp | 13 | ||||
-rw-r--r-- | ace/OS.cpp | 2 | ||||
-rw-r--r-- | ace/OS.h | 21 | ||||
-rw-r--r-- | ace/OS.i | 8 | ||||
-rw-r--r-- | ace/README | 1 | ||||
-rw-r--r-- | ace/SOCK_Connector.cpp | 3 | ||||
-rw-r--r-- | ace/SOCK_Stream.cpp | 7 | ||||
-rw-r--r-- | ace/Strategies_T.cpp | 32 | ||||
-rw-r--r-- | ace/Strategies_T.h | 20 | ||||
-rw-r--r-- | ace/Synch.h | 4 | ||||
-rw-r--r-- | ace/Task.cpp | 8 | ||||
-rw-r--r-- | ace/XtReactor.cpp | 24 | ||||
-rw-r--r-- | ace/config-aix-4.2.x.h | 1 | ||||
-rw-r--r-- | ace/config-irix6.2-sgic++.h | 1 | ||||
-rw-r--r-- | ace/config-linux-lxpthreads.h | 4 | ||||
-rw-r--r-- | ace/config-osf1-4.0-g++.h | 1 | ||||
-rw-r--r-- | ace/config-osf1-4.0.h | 1 | ||||
-rw-r--r-- | ace/config-sco-5.0.0-mit-pthread.h | 2 | ||||
-rw-r--r-- | examples/Logger/simple-server/Logging_Handler.cpp | 3 | ||||
-rw-r--r-- | tests/Makefile | 1 | ||||
-rw-r--r-- | tests/Process_Strategy_Test.cpp | 353 |
23 files changed, 535 insertions, 81 deletions
diff --git a/ChangeLog-97a b/ChangeLog-97a index 5e94a2332be..7f12ceaa08f 100644 --- a/ChangeLog-97a +++ b/ChangeLog-97a @@ -1,30 +1,56 @@ -Tue Apr 15 23:16:43 1997 <harrison@samba.cs.wustl.edu> +Wed Apr 16 04:07:50 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - * ace/Map_Manager.cpp: The Map_Manager now explicitly calls the - destructors of Map_Entry objects before freeing up the space. - Not sure why we were not doing this before. + * ace/Strategies_T: Widened the constructor interface for + ACE_Process_Strategy based on the feedback I got from + implementing the Process_Strategy_Test.cpp program. -Tue Apr 15 17:09:33 1997 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> + * tests/Process_Strategy_Test.cpp: Added an interesting new test + that illustrates the use of the ACE_Process_Strategy and the + ACE_File_Lock. To exercise this program, you can telnet to it + and type "read" and "inc" to query and change the count of + the numbers in the file, respectively. - * examples/Logger: Added MSVC++ makefile to Acceptor-server - and client. + * ace/Connector.cpp (create_AST): I fixed a couple of things + in Connector.cpp: -Tue Apr 15 21:51:45 1997 James C Hu <jxh@polka.cs.wustl.edu> + - In create_AST, it needs to save and restore errno, else it + gets wiped on Win32 and other platforms. - * apps/JAWS/server/IO.cpp: Added a template instance for - ACE_Singleton so it would link using GCC. Removed GCC - warnings. + - On Win32 when a non-blocking connect completes and handle_output is + called, it tries to get the peer address. If done too quickly, it + fails. I put in a Sleep(0) call. I think this is not a great + solution, but I don't have a better one yet. + + Thanks to Steve Huston <shuston@riverace.com> for fixing + these bugs. - * apps/JAWS/server/HTTP_Server.cpp: Added template instances for - LOCK_SOCK_Acceptor, ACE_Task, ACE_Thru_Task, ACE_Message_Queue, - ACE_Module so it would link using GCC. Removed GCC warnings. +Tue Apr 15 17:09:33 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - * apps/JAWS/server/HTTP_Server_T.cpp: Removed template instance of - LOCK_SOCK_Acceptor, since it was not really being compiled. + * ace/SOCK_Stream.cpp (close): Removed the call to close_writer() + on UNIX since that doesn't do the correct thing in many + cases since it causes a protocol transmission which isn't + what we want if we're using fork(). - * apps/JAWS/server/HTTP_Handler.cpp: Removed GCC warnings. + * ace/Strategies_T.cpp (activate_svc_handler): Added a call to + svc_handler->destroy() in the parent since we don't need it and + we're leaking descriptors and memory otherwise... Thanks to + Kevin Boyle <kboyle@sanwafp.com> for reporting this. -Tue Apr 15 17:09:33 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + * ace/OS.i (thr_sigsetmask): Replaced the use of + PTHREADS_1003_DOT_1C with ACE_HAS_PTHREAD_SIGMASK. Thanks to + Arturo Montes <mitosys@colomsat.net.co> for suggesting this. + + * ace: Changed all uses of ACE_HAS_PTHREADS_XAVIER to + ACE_HAS_PTHREAD_SIGMASK, which is more descriptive. Thanks to + Arturo Montes <mitosys@colomsat.net.co> for suggesting this. + + * ace/config-aix-4.2.x.h: Added #define ACE_LACKS_RWLOCK_T to make + things compile with AIX 4.2. Thanks to Jeremy Buch + <davinci@nortel.ca> for reporting this. + + * ace/XtReactor.cpp (register_handler_i): Added "[]" to delete + this->ids_ since it is an array. Thanks to Jean-Marc Strauss + <strauss@club-internet.fr> for reporting this. * netsvcs/lib: Moved all the class definitions into the *.h files to avoid complaints from the IBM C++ compiler. @@ -104,6 +130,48 @@ Tue Apr 15 17:09:33 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> platforms. Thanks to Ganesh Pai <gpai@voicetek.com> for reporting this. +Tue Apr 15 23:16:43 1997 <harrison@samba.cs.wustl.edu> + + * ace/[Hash_]Map_Manager.cpp: The [Hash_]Map_Manager now + explicitly calls the destructors of Map_Entry objects before + freeing up the space. Not sure why we were not doing this + before... + +Tue Apr 15 17:09:33 1997 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> + + * examples/Logger: Added MSVC++ makefile to Acceptor-server + and client. + +Tue Apr 15 21:51:45 1997 James C Hu <jxh@polka.cs.wustl.edu> + + * apps/JAWS/server/IO.cpp: Added a template instance for + ACE_Singleton so it would link using GCC. Removed GCC + warnings. + + * apps/JAWS/server/HTTP_Server.cpp: Added template instances for + LOCK_SOCK_Acceptor, ACE_Task, ACE_Thru_Task, ACE_Message_Queue, + ACE_Module so it would link using GCC. Removed GCC warnings. + + * apps/JAWS/server/HTTP_Server_T.cpp: Removed template instance of + LOCK_SOCK_Acceptor, since it was not really being compiled. + +Tue Apr 15 21:51:45 1997 James C Hu <jxh@polka.cs.wustl.edu> + + * apps/JAWS/server/IO.cpp: Added a template instance for + ACE_Singleton so it would link using GCC. Removed GCC + warnings. + + * apps/JAWS/server/HTTP_Server.cpp: Added template instances for + LOCK_SOCK_Acceptor, ACE_Task, ACE_Thru_Task, + ACE_Message_Queue, ACE_Module so it would link using GCC. + Removed GCC warnings. + + * apps/JAWS/server/HTTP_Server_T.cpp: Removed template + instance of LOCK_SOCK_Acceptor, since it was not really + being compiled. + + * apps/JAWS/server/HTTP_Handler.cpp: Removed GCC warnings. + Tue Apr 15 13:01:13 1997 David L. Levine <levine@cs.wustl.edu> * ace/Token_Request_Reply.cpp (ctor): added initialization of @@ -503,6 +503,8 @@ Darrell Brunsch <brunsch@cs.wustl.edu> Mike Bernat <sagmb@sagus.com> Brian Mendel <bmendel@mdc.com> Dave Mayerhoefer <mayerhoefer@svappl36.mdc.com> +Jeremy Buch <davinci@nortel.ca> +Kevin Boyle <kboyle@sanwafp.com> I would particularly like to thank Paul Stephenson, who worked with me at Ericsson and is now at ObjectSpace. Paul devised the recursive diff --git a/ace/Connector.cpp b/ace/Connector.cpp index bcc8c46ef4c..e2654f6a95c 100644 --- a/ace/Connector.cpp +++ b/ace/Connector.cpp @@ -282,6 +282,13 @@ ACE_Connector<SH, PR_CO_2>::handle_output (ACE_HANDLE handle) PR_AD raddr; +#if defined (ACE_HAS_BROKEN_NON_BLOCKING_CONNECTS) + // Win32 has a timing problem - if you check to see if the + // connection has completed too fast, it will fail - so wait a bit + // to let it catch up. + ACE_OS::sleep (0); +#endif /* ACE_HAS_BROKEN_NON_BLOCKING_CONNECTS */ + // Check to see if we're connected. if (ast->svc_handler ()->peer ().get_remote_addr (raddr) != -1) this->activate_svc_handler (ast->svc_handler ()); @@ -376,6 +383,7 @@ template <class SH, PR_CO_1> int ACE_Connector<SH, PR_CO_2>::create_AST (SH *sh, const ACE_Synch_Options &synch_options) { + int error = errno; ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::create_AST"); AST *ast; @@ -406,13 +414,16 @@ ACE_Connector<SH, PR_CO_2>::create_AST (SH *sh, goto fail3; ast->cancellation_id (cancellation_id); + // Reset this because something might have gone wrong + // elsewhere... + errno = error; return 0; } else { // Reset this because something might have gone wrong // elsewhere... - errno = EWOULDBLOCK; + errno = error; // EWOULDBLOCK return 0; // Ok, everything worked just fine... } } diff --git a/ace/OS.cpp b/ace/OS.cpp index 08eaded2edc..5247b79cf81 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -1453,7 +1453,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func, # if defined (ACE_HAS_DCETHREADS) && !defined (ACE_HAS_SETKIND_NP) sparam.sched_priority = ACE_MIN (priority, PRIORITY_MAX); -# elif defined(ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_XAVIER) +# elif defined(ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREAD_SIGMASK) sparam.sched_priority = ACE_MIN (priority, PTHREAD_MAX_PRIORITY); # elif defined (PTHREAD_MAX_PRIORITY) /* For MIT pthreads... */ sparam.prio = ACE_MIN (priority, PTHREAD_MAX_PRIORITY); @@ -3102,27 +3102,6 @@ private: // depending on whether ANSI/ISO exception handling semantics are // being used). -#if 0 -#define ACE_NEW(POINTER,CONSTRUCTOR) \ - do { POINTER = new CONSTRUCTOR; \ - if (POINTER == 0) { errno = ENOMEM; return; } \ - else if (ACE_LOG_MSG->op_status () == -1) { \ - int ace_error = ACE_LOG_MSG->errnum (); \ - delete POINTER; POINTER = 0; \ - ACE_LOG_MSG->op_status (-1); \ - errno = ace_error; return; \ - } } while (0) -#define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \ - do { POINTER = new CONSTRUCTOR; \ - if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \ - else if (ACE_LOG_MSG->op_status () == -1) { \ - int ace_error = ACE_LOG_MSG->errnum (); \ - delete POINTER; POINTER = 0; \ - ACE_LOG_MSG->op_status (-1); \ - errno = ace_error; return RET_VAL; \ - } } while (0) -#endif /* 0 */ - #define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \ do { POINTER = new CONSTRUCTOR; \ if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \ @@ -3978,19 +3978,13 @@ ACE_OS::thr_sigsetmask (int how, ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm), ace_result_), int, -1); -#elif defined (ACE_HAS_PTHREADS_1003_DOT_1C) - // PTHREADS_1003_DOT_1C is NOT a subcase of DCETHREADS! +#elif defined (ACE_HAS_PTHREAD_SIGMASK) ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), ace_result_), int, -1); #elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS) -#if defined (ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_XAVIER) - ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), - ace_result_),int, -1); -#else // as far as I can tell, this is now pthread_sigaction() -- jwr ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigaction (how, nsm, osm), ace_result_), int, -1); -#endif /* ACE_HAS_IRIX62_THREADS */ #elif defined (ACE_HAS_WTHREADS) ACE_UNUSED_ARG (osm); ACE_UNUSED_ARG (nsm); diff --git a/ace/README b/ace/README index 79196a99abf..4e9b7aed9dd 100644 --- a/ace/README +++ b/ace/README @@ -82,6 +82,7 @@ ACE_HAS_PTHREAD_DSTATE_PTR pthread_attr_setdetachstate() takes pointer to 2nd a ACE_HAS_PTHREAD_EQUAL Platform has pthread_equal(). ACE_HAS_PTHREAD_GETSPECIFIC_DATAPTR pthread_getspecific() takes a data pointer for 2nd arg. ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP Platform has pthread_mutexattr_setkind_np(). +ACE_HAS_PTHREAD_SIGMASK Platform has pthread_sigmask() defined. ACE_HAS_PTHREAD_T Platform has pthread_t defined. ACE_HAS_PTHREAD_YIELD_VOIDPTR pthread_yield() takes a void pointer arg. ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS Platform will recurse infinitely on thread exits from TSS cleanup routines (e.g., AIX). diff --git a/ace/SOCK_Connector.cpp b/ace/SOCK_Connector.cpp index e7224370b1f..e38ac60e8fd 100644 --- a/ace/SOCK_Connector.cpp +++ b/ace/SOCK_Connector.cpp @@ -109,6 +109,9 @@ ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream, { ACE_TRACE ("ACE_SOCK_Connector::complete"); #if defined (ACE_HAS_BROKEN_NON_BLOCKING_CONNECTS) + // Win32 has a timing problem - if you check to see if the + // connection has completed too fast, it will fail - so wait a bit + // to let it catch up. ACE_OS::sleep (0); #endif /* ACE_HAS_BROKEN_NON_BLOCKING_CONNECTS */ ACE_HANDLE h = ACE::handle_timed_complete (this->get_handle (), tv); diff --git a/ace/SOCK_Stream.cpp b/ace/SOCK_Stream.cpp index eac7daf021d..2acb22f962c 100644 --- a/ace/SOCK_Stream.cpp +++ b/ace/SOCK_Stream.cpp @@ -15,10 +15,15 @@ ACE_SOCK_Stream::dump (void) const int ACE_SOCK_Stream::close (void) { +#if defined (ACE_WIN32) // We need the following call to make things work correctly on // Win32, which requires use to do a <close_writer> before doing the - // close in order to avoid losing data. + // close in order to avoid losing data. Note that we don't need to + // do this on UNIX since it doesn't have this "feature". Moreover, + // this will cause subtle problems on UNIX due to the way that + // fork() works. this->close_writer (); +#endif /* ACE_WIN32 */ // Close down the socket. return ACE_SOCK::close (); } diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp index 7716ae84a15..2559fde2f42 100644 --- a/ace/Strategies_T.cpp +++ b/ace/Strategies_T.cpp @@ -178,7 +178,7 @@ ACE_Concurrency_Strategy<SVC_HANDLER>::dump (void) const template <class SVC_HANDLER> int ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg) + void *arg) { ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler"); // Delegate control to the application-specific service @@ -249,7 +249,7 @@ ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy (void) template <class SVC_HANDLER> int ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg) + void *arg) { ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler"); // Call up to our parent to do the SVC_HANDLER initialization. @@ -327,7 +327,7 @@ ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy (voi ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy"); if (this->acceptor_.close () == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "close")); + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close")); } template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> void @@ -382,19 +382,25 @@ ACE_Process_Strategy<SVC_HANDLER>::dump (void) const } template <class SVC_HANDLER> int -ACE_Process_Strategy<SVC_HANDLER>::open (int n_processes) +ACE_Process_Strategy<SVC_HANDLER>::open (size_t n_processes, + ACE_Event_Handler *acceptor, + ACE_Reactor *reactor) { ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::open"); this->n_processes_ = n_processes; + this->acceptor_ = acceptor; + this->reactor_ = reactor; return 0; } template <class SVC_HANDLER> -ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (int n_processes) +ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (size_t n_processes, + ACE_Event_Handler *acceptor, + ACE_Reactor *reactor) { ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy"); - this->open (n_processes); + this->open (n_processes, acceptor, reactor); } template <class SVC_HANDLER> @@ -408,17 +414,29 @@ ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handle void *arg) { ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler"); - switch (ACE_OS::fork ()) + + switch (ACE_OS::fork ("child")) { case -1: ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), -1); /* NOTREACHED */ case 0: // In child process. + + // Close down the SOCK_Acceptor's handle since we don't need to + // keep it open. + if (this->acceptor_ != 0) + // Ignore the return value here... + (void) this->reactor_->remove_handler (this->acceptor_, + ACE_Event_Handler::ACCEPT_MASK); + // Call up to our ancestor in the inheritance to do the // SVC_HANDLER initialization. return this->inherited::activate_svc_handler (svc_handler, arg); /* NOTREACHED */ default: // In parent process. + // We need to close down the <SVC_HANDLER> here because it's + // running in the child. + svc_handler->destroy (); return 0; } } diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h index 2868c8fe02e..66947c5b943 100644 --- a/ace/Strategies_T.h +++ b/ace/Strategies_T.h @@ -254,10 +254,14 @@ class ACE_Process_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> public: // = Intialization and termination methods. - ACE_Process_Strategy (int n_processes = 1); + ACE_Process_Strategy (size_t n_processes = 1, + ACE_Event_Handler *acceptor = 0, + ACE_Reactor * = 0); // Initialize the strategy. - virtual int open (int n_processes = 1); + virtual int open (size_t n_processes = 1, + ACE_Event_Handler *acceptor = 0, + ACE_Reactor * = 0); // Initialize the strategy. virtual ~ACE_Process_Strategy (void); @@ -279,8 +283,18 @@ public: protected: typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; - int n_processes_; + size_t n_processes_; // Number of processes to spawn. + + ACE_Event_Handler *acceptor_; + // This is the <Acceptor> in the parent is listening on. We need to + // make sure that we remove it from the Reactor and close it down in + // the child. + + ACE_Reactor *reactor_; + // This is the <Reactor> the child is using in conjunction with the + // <Acceptor>. We need to remove the <Acceptor> from this <Reactor> + // in the child. }; template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> diff --git a/ace/Synch.h b/ace/Synch.h index 1e605c23526..2af4bd0c27c 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -130,12 +130,12 @@ public: // Conditionally acquire a read lock (i.e., won't block). ACE_HANDLE get_handle (void); - // Get underlying <ACE_HANDLE>. + // Get underlying <ACE_HANDLE> for the file. void set_handle (ACE_HANDLE); // Set underlying <ACE_HANDLE>. Note that this method assumes // ownership of the <handle> and will close it down in <remove>. If - // you want the <handle> stays open when <remove> is called make + // you want the <handle> to stay open when <remove> is called make // sure to call <dup> on the <handle> before closing it. void dump (void) const; diff --git a/ace/Task.cpp b/ace/Task.cpp index 68388a29071..e4402efb841 100644 --- a/ace/Task.cpp +++ b/ace/Task.cpp @@ -18,7 +18,7 @@ ACE_Thread_Mutex ACE_Task_Exit::ace_task_lock_; // NOTE: this preprocessor directive should match the one in // ACE_Task_Base::svc_run () below. This prevents the two statics // from being defined. -#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (ACE_HAS_PTHREADS_XAVIER) +#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (ACE_HAS_PTHREAD_SIGMASK) ACE_Task_Exit * ACE_Task_Exit::instance (void) { @@ -40,7 +40,7 @@ ACE_Task_Exit::instance (void) return ACE_TSS_GET (instance_, ACE_Task_Exit); } -#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE && ! ACE_HAS_PTHREADS_XAVIER */ +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE && ! ACE_HAS_PTHREAD_SIGMASK */ // Grab hold of the Task * so that we can close() it in the @@ -228,7 +228,7 @@ ACE_Task_Base::svc_run (void *args) // With the Xavier Pthreads package, the exit_hook in TSS causes // a seg fault. So, this works around that by creating exit_hook // on the stack. -#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (ACE_HAS_PTHREADS_XAVIER) +#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (ACE_HAS_PTHREAD_SIGMASK) // Obtain our thread-specific exit hook and make sure that it knows // how to clean us up! Note that we never use this pointer directly // (it's stored in thread-specific storage), so it's ok to @@ -242,7 +242,7 @@ ACE_Task_Base::svc_run (void *args) // So, threads shouldn't exit that way. Instead, they should // return from svc (). ACE_Task_Exit exit_hook; -#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE && ! ACE_HAS_PTHREADS_XAVIER */ +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE && ! ACE_HAS_PTHREAD_SIGMASK */ exit_hook.set_task (t); diff --git a/ace/XtReactor.cpp b/ace/XtReactor.cpp index 62eb55ece09..95026865193 100644 --- a/ace/XtReactor.cpp +++ b/ace/XtReactor.cpp @@ -11,8 +11,8 @@ struct ACE_XtReactorID { - XtInputId id; - int good_id; + XtInputId id_; + int good_id_; }; ACE_ALLOC_HOOK_DEFINE (ACE_XtReactor) @@ -47,7 +47,7 @@ ACE_XtReactor::ACE_XtReactor (XtAppContext context, ACE_XtReactor::~ACE_XtReactor (void) { - delete this->ids_; + delete [] this->ids_; } // This is just the wait_for_multiple_events from ace/Reactor.cpp but @@ -209,10 +209,10 @@ ACE_XtReactor::register_handler_i (ACE_HANDLE handle, more[i] = ids_[i]; for (i = this->id_len_; i < handle + 1; i++) - more[i].good_id = 0; + more[i].good_id_ = 0; id_len_ = handle + 1; - delete this->ids_; + delete [] this->ids_; ids_ = more; } @@ -229,15 +229,15 @@ ACE_XtReactor::register_handler_i (ACE_HANDLE handle, if (condition != 0) { - if (ids_[handle].good_id) - ::XtRemoveInput (ids_[handle].id); + if (ids_[handle].good_id_) + ::XtRemoveInput (ids_[handle].id_); - ids_[handle].id = ::XtAppAddInput (context_, + ids_[handle].id_ = ::XtAppAddInput (context_, handle, (XtPointer) condition, InputCallbackProc, (XtPointer) this); - ids_[handle].good_id = 1; + ids_[handle].good_id_ = 1; } return 0; } @@ -261,11 +261,11 @@ ACE_XtReactor::remove_handler_i (ACE_HANDLE handle, if (handle <= id_len_) { - if (ids_[handle].good_id) - ::XtRemoveInput (ids_[handle].id); + if (ids_[handle].good_id_) + ::XtRemoveInput (ids_[handle].id_); else ACE_DEBUG ((LM_DEBUG, "Handle id is not good %d\n", handle)); - ids_[handle].good_id = 0; + ids_[handle].good_id_ = 0; } else ACE_DEBUG ((LM_DEBUG, "Handle out of range %d\n", handle)); diff --git a/ace/config-aix-4.2.x.h b/ace/config-aix-4.2.x.h index d3849672fdc..f574d16571d 100644 --- a/ace/config-aix-4.2.x.h +++ b/ace/config-aix-4.2.x.h @@ -108,6 +108,7 @@ // EYE assume it does for now. #define ACE_LACKS_PTHREAD_THR_SIGSETMASK #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T #define ACE_PTHREADS_MAP // include there diff --git a/ace/config-irix6.2-sgic++.h b/ace/config-irix6.2-sgic++.h index 98ac4d0ec6b..f4d4ad3c3ef 100644 --- a/ace/config-irix6.2-sgic++.h +++ b/ace/config-irix6.2-sgic++.h @@ -14,6 +14,7 @@ #define ACE_CONFIG_H #define ACE_HAS_IRIX62_THREADS +#define ACE_HAS_PTHREAD_SIGMASK // Needed for the threading stuff? #include /**/ <sched.h> diff --git a/ace/config-linux-lxpthreads.h b/ace/config-linux-lxpthreads.h index 02c0781260f..4ceb06f27e9 100644 --- a/ace/config-linux-lxpthreads.h +++ b/ace/config-linux-lxpthreads.h @@ -128,12 +128,12 @@ // And they're even POSIX pthreads (MIT implementation) #define ACE_HAS_PTHREADS -#define ACE_HAS_PTHREADS_XAVIER // JCEJ 12/19/96 +#define ACE_HAS_PTHREAD_SIGMASK // JCEJ 12/19/96 #define ACE_MT_SAFE // JCEJ 12/22/96 #1 #define ACE_HAS_THREAD_SPECIFIC_STORAGE // jcej 12/22/96 #2 #define PTHREAD_MIN_PRIORITY 0 // JCEJ 12/22/96 #3 -#if defined(ACE_HAS_PTHREADS_XAVIER) +#if defined(ACE_HAS_PTHREAD_SIGMASK) # define PTHREAD_MAX_PRIORITY 99 // CJC 02/11/97 #else # define PTHREAD_MAX_PRIORITY 32 // JCEJ 12/22/96 #3 diff --git a/ace/config-osf1-4.0-g++.h b/ace/config-osf1-4.0-g++.h index 9b1ec88e68b..94911f82b55 100644 --- a/ace/config-osf1-4.0-g++.h +++ b/ace/config-osf1-4.0-g++.h @@ -207,6 +207,7 @@ // uses ctime_r & asctime_r with only two parameters vs. three #define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_PTHREAD_SIGMASK #define ACE_HAS_BROKEN_IF_HEADER #define ACE_HAS_REENTRANT_FUNCTIONS #define DIGITAL_UNIX diff --git a/ace/config-osf1-4.0.h b/ace/config-osf1-4.0.h index e3cf41dc006..815679ce029 100644 --- a/ace/config-osf1-4.0.h +++ b/ace/config-osf1-4.0.h @@ -187,6 +187,7 @@ // uses ctime_r & asctime_r with only two parameters vs. three #define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R +#define ACE_HAS_PTHREAD_SIGMASK #define ACE_HAS_BROKEN_IF_HEADER //#define ACE_HAS_REENTRANT_FUNCTIONS #define DIGITAL_UNIX diff --git a/ace/config-sco-5.0.0-mit-pthread.h b/ace/config-sco-5.0.0-mit-pthread.h index 6d7b5144024..dcff4c82637 100644 --- a/ace/config-sco-5.0.0-mit-pthread.h +++ b/ace/config-sco-5.0.0-mit-pthread.h @@ -129,7 +129,7 @@ #define ACE_HAS_THREAD_SPECIFIC_STORAGE #define ACE_HAS_PTHREADS #define ACE_HAS_PTHREAD_T -#define ACE_HAS_PTHREADS_XAVIER +#define ACE_HAS_PTHREAD_SIGMASK #define ACE_HAS_SIGWAIT //#define ACE_HAS_ONEARG_SIGWAIT //#define ACE_HAS_PTHREAD_YIELD_VOID_PTR diff --git a/examples/Logger/simple-server/Logging_Handler.cpp b/examples/Logger/simple-server/Logging_Handler.cpp index 323f11483e1..19944618532 100644 --- a/examples/Logger/simple-server/Logging_Handler.cpp +++ b/examples/Logger/simple-server/Logging_Handler.cpp @@ -54,7 +54,8 @@ Logging_Handler::handle_input (ACE_HANDLE) "client logger", this->host_name_), -1); /* NOTREACHED */ case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon at host %s (fd = %d)\n", + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) closing log daemon at host %s (fd = %d)\n", this->host_name_, this->get_handle ()), -1); /* NOTREACHED */ case sizeof (size_t): diff --git a/tests/Makefile b/tests/Makefile index c26303c1d96..63454ce9e62 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -22,6 +22,7 @@ BIN = Barrier_Test \ Mutex_Test \ Naming_Test \ Process_Mutex_Test \ + Process_Strategy_Test \ Priority_Buffer_Test \ Priority_Task_Test \ Pipe_Test \ diff --git a/tests/Process_Strategy_Test.cpp b/tests/Process_Strategy_Test.cpp new file mode 100644 index 00000000000..e53d3101364 --- /dev/null +++ b/tests/Process_Strategy_Test.cpp @@ -0,0 +1,353 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Process_Strategy_Test.cpp +// +// = DESCRIPTION +// This is a test of the <ACE_Strategy_Acceptor> and +// <ACE_File_Lock> classes. The <ACE_Strategy_Acceptor> uses the +// <ACE_Process_Strategy>, which forks a process-per-connection +// and runs as a concurrent server. This concurrent server +// queries and increments a "counting value" in a file. +// +// To execute this test program you can simply start the server +// process and connect to it via telnet. If you type "inc" and +// "read" in the telnet window you'll exercise the functionality +// of the server. +// +// = AUTHOR +// Doug Schmidt and Kevin Boyle <kboyle@sanwafp.com> +// +// ============================================================================ + +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Strategies_T.h" +#include "ace/Service_Config.h" +#include "test_config.h" + +typedef ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> SVC_HANDLER; + +class Counting_Service : public SVC_HANDLER + // = TITLE + // Reads and increments the count in a shared file. + // + // = DESCRIPTION + // Objects of this class execute in a separate process as a + // result of the <ACE_Strategy_Acceptor> and + // <ACE_Process_Strategy>. +{ +public: + Counting_Service (ACE_Thread_Manager * = 0, ACE_File_Lock * = 0); + // Constructor. + + virtual int open (void *v); + // Hook that is used to initialize the service (called by the + // <ACE_Strategy_Acceptor::handle_input>). + +protected: + // = Operations corresponding to requests from the client. + virtual int read (void); + // Execute the read operation on the file. + + virtual int inc (void); + // Execute the increment operation on the file. + + // = Hooks called by <Reactor> and <Strategy_Acceptor>. + + virtual int handle_input (ACE_HANDLE p); + // Hook called by the <Reactor> when data arrives from the client. + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + // Close down the server and exit the process. + +private: + ACE_File_Lock *file_lock_; + // Lock for the counting file. +}; + +typedef ACE_Strategy_Acceptor <Counting_Service, ACE_SOCK_ACCEPTOR> ACCEPTOR; + +class Counting_Acceptor : public ACCEPTOR + // = TITLE + // Factory that accepts the connection and creates the + // <Counting_Service> handler. This illustrates both the + // Strategy pattern as a mean to configure the + // <ACE_Strategy_Acceptor> (i.e., via the + // <ACE_Process_Strategy>), as well as the Template Method + // pattern (via the <make_svc_handler> method). +{ + friend class Counting_Service; +public: + Counting_Acceptor (LPCTSTR filename); + // Constructor. + + virtual int make_svc_handler (Counting_Service *&); + // Factory Method that makes a new <Counting_Service> in response to + // a connection from a client. + + virtual int open (const ACE_INET_Addr &, + ACE_Reactor * = ACE_Service_Config::reactor ()); + // Initialize the Acceptor activation strategy. + + virtual int handle_signal (int, siginfo_t *, ucontext_t *); + // Catch the SIGCHLD signal and reap the exiting child processes. + +private: + ACE_File_Lock file_lock_; + // Lock for the counting file. + + ACE_Process_Strategy<Counting_Service> proc_strategy_; + // Activation strategy that forks a new process for each client + // connection. +}; + +// Factory Method that creates a new <Counting_Service>. + +int +Counting_Acceptor::make_svc_handler (Counting_Service *&svc) +{ + ACE_NEW_RETURN (svc, Counting_Service (0, &this->file_lock_), -1); + return 0; +} + +// Reap child processes. + +int +Counting_Acceptor::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) signal %S\n", signum)); + + pid_t pid; + + while ((pid = ACE_OS::waitpid (-1, 0, WNOHANG)) > 0) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) reaping child %d\n", pid)); + + return 0; +} + +Counting_Acceptor::Counting_Acceptor (LPCTSTR filename) + : file_lock_ (filename, + O_RDWR | O_CREAT, + ACE_DEFAULT_FILE_PERMS) +{ + // Note that this object lives beyond the lifetime of the Acceptor. + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) opening %s on handle %d.\n", + filename, this->file_lock_.get_handle ())); + + int count = 0; + + // Store the initial value of the count in the file. + if (ACE_OS::write (this->file_lock_.get_handle (), + (const void *) &count, + sizeof count) != sizeof count) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "write")); +} + +int +Counting_Acceptor::open (const ACE_INET_Addr &addr, + ACE_Reactor *reactor) +{ + // Initialize the Concurrency strategy. + if (this->proc_strategy_.open (1, this, reactor) == -1) + return -1; + + // Open the <Strategy_Acceptor>. + else if (ACCEPTOR::open (addr, + reactor, + 0, + 0, + &this->proc_strategy_) == -1) + return -1; + + // Register to handle <SIGCHLD> when a child exits. + else if (reactor->register_handler (SIGCHLD, this) == -1) + return -1; + else + { + ACE_INET_Addr my_addr; + + // Find out what port we're really connected to. + if (this->acceptor ().get_local_addr (my_addr) == -1) + return -1; + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) port = %d, handle = %d\n", + my_addr.get_port_number (), + this->get_handle ())); + return 0; + } +} + +Counting_Service::Counting_Service (ACE_Thread_Manager *, + ACE_File_Lock *file_lock) + : file_lock_ (file_lock) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) creating the Counting_Service\n")); +} + +// Read the current value from the shared file and return it to the +// client. + +int +Counting_Service::read (void) +{ + ACE_READ_GUARD_RETURN (ACE_File_Lock, ace_mon, *this->file_lock_, -1); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) reading on handle %d.\n", + this->file_lock_->get_handle ())); + + int count; + if (ACE_OS::pread (this->file_lock_->get_handle (), + (void *) &count, + sizeof count, + 0) != sizeof count) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "read"), -1); + + char buf[BUFSIZ]; + + int n = ACE_OS::sprintf (buf, "count = %d\n", count); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) count = %d\n", + count)); + + if (this->peer ().send_n (buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "send_n"), -1); + return 0; +} + +// Increment the current value in the shared file by 1. + +int +Counting_Service::inc (void) +{ + ACE_WRITE_GUARD_RETURN (ACE_File_Lock, ace_mon, *this->file_lock_, -1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) incrementing on handle %d.\n", + this->file_lock_->get_handle ())); + + int count; + if (ACE_OS::pread (this->file_lock_->get_handle (), + (void *) &count, + sizeof count, + 0) != sizeof count) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "read"), -1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) incrementing count from %d to %d\n", + count, count + 1)); + count++; + + if (ACE_OS::pwrite (this->file_lock_->get_handle (), + (const void *) &count, + sizeof count, + 0) != sizeof count) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "write"), -1); + return 0; +} + +// Receive the request from the client and call the appropriate +// operation. + +int +Counting_Service::handle_input (ACE_HANDLE) +{ + char buf[BUFSIZ]; + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reading from peer on %d\n", + this->peer ().get_handle ())); + + ssize_t bytes = this->peer ().recv (buf, sizeof buf); + + if (bytes <= 0 || buf[0] == EOF) + return -1; + else + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) input on %d is %*s\n", + this->peer ().get_handle (), bytes, buf)); + + // Read and return the current value in the file. + if (ACE_OS::strncmp (buf, "read", 4) == 0) + return this->read (); + // Increment the current value in the file. + else if (ACE_OS::strncmp (buf, "inc", 3) == 0) + return this->inc (); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) no match...\n")); + + return 0; + } +} + +int +Counting_Service::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) opening service\n")); + + // Register the new handle with the reactor and look for new input + // in the handle_input routine. + + if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "(%P|%t) register_handler"), -1); + + // We need to rerun the event loop here since we ended up here due + // to being fork'd and we can't just return to our context since + // it's in the wrong location in the process. + ACE_Service_Config::run_reactor_event_loop (); + + /* NOTREACHED */ + return 0; +} + +// Hook called when the child is going to exit. + +int +Counting_Service::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) About to exit from the child\n")); + + // Exit the child. + ACE_OS::exit (0); + return 0; +} + +int +main (int argc, char *argv[]) +{ + // ACE_START_TEST ("Process_Stratey_Test"); + ACE_Service_Config svc_conf; + + // Initialize the counting file. + Counting_Acceptor counting_acceptor ("counting_file"); + + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + ACE_INET_Addr addr (port); + + // Open the Acceptor. + if (counting_acceptor.open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + // Run the event loop. + + ACE_Service_Config::run_reactor_event_loop (); + + // ACE_END_TEST; + return 0; +} |