diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1996-12-02 02:31:08 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1996-12-02 02:31:08 +0000 |
commit | 09593654ece6c713b2690f7dd5cc0cc42f9ff1bf (patch) | |
tree | d3c213e139b90e270be9a81875818cfa5a701ed4 | |
parent | 12d1056218c5f7f7ed7664da05d9ea4faaaf5b86 (diff) | |
download | ATCD-09593654ece6c713b2690f7dd5cc0cc42f9ff1bf.tar.gz |
hello
-rw-r--r-- | ace/Activation_Queue.cpp | 2 | ||||
-rw-r--r-- | ace/Activation_Queue.h | 1 | ||||
-rw-r--r-- | ace/Event_Handler.cpp | 13 | ||||
-rw-r--r-- | ace/Event_Handler.h | 18 | ||||
-rw-r--r-- | ace/Memory_Pool.cpp | 164 | ||||
-rw-r--r-- | ace/Memory_Pool.h | 81 | ||||
-rw-r--r-- | ace/Message_Queue.cpp | 213 | ||||
-rw-r--r-- | ace/Message_Queue.h | 34 | ||||
-rw-r--r-- | ace/Message_Queue.i | 16 | ||||
-rw-r--r-- | ace/OS.h | 2 | ||||
-rw-r--r-- | ace/Reactor.cpp | 27 | ||||
-rw-r--r-- | ace/ReactorEx.cpp | 109 | ||||
-rw-r--r-- | ace/ReactorEx.h | 36 | ||||
-rw-r--r-- | ace/SV_Semaphore_Complex.cpp | 14 | ||||
-rw-r--r-- | ace/SV_Semaphore_Simple.cpp | 31 | ||||
-rw-r--r-- | ace/SV_Semaphore_Simple.h | 8 | ||||
-rw-r--r-- | ace/SV_Semaphore_Simple.i | 22 | ||||
-rw-r--r-- | ace/Strategies.cpp | 496 | ||||
-rw-r--r-- | ace/Strategies.h | 419 | ||||
-rw-r--r-- | ace/Strategies_T.cpp | 498 | ||||
-rw-r--r-- | ace/Strategies_T.h | 433 | ||||
-rw-r--r-- | ace/Synch.h | 2 | ||||
-rw-r--r-- | ace/Task_T.h | 8 |
23 files changed, 1521 insertions, 1126 deletions
diff --git a/ace/Activation_Queue.cpp b/ace/Activation_Queue.cpp index 091a8b3c7bd..c7a78713173 100644 --- a/ace/Activation_Queue.cpp +++ b/ace/Activation_Queue.cpp @@ -68,5 +68,5 @@ ACE_Activation_Queue::enqueue (ACE_Method_Object *mo, ACE_NEW_RETURN (mb, ACE_Message_Block ((char *) mo), -1); - return this->queue_->enqueue (mb, tv); + return this->queue_->enqueue_prio (mb, tv); } diff --git a/ace/Activation_Queue.h b/ace/Activation_Queue.h index 2ab871dce7e..0b8e06faab5 100644 --- a/ace/Activation_Queue.h +++ b/ace/Activation_Queue.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY diff --git a/ace/Event_Handler.cpp b/ace/Event_Handler.cpp index e23bfb231f4..d1f11cfc29b 100644 --- a/ace/Event_Handler.cpp +++ b/ace/Event_Handler.cpp @@ -181,3 +181,16 @@ ACE_Event_Handler::proactor (void) const return this->proactor_; } + +ACE_Notification_Buffer::ACE_Notification_Buffer (void) +{ + ACE_TRACE ("ACE_Notification_Buffer::ACE_Notification_Buffer"); +} + +ACE_Notification_Buffer::ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) + : eh_ (eh), + mask_ (mask) +{ + ACE_TRACE ("ACE_Notification_Buffer::ACE_Notification_Buffer"); +} diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h index cad6955dfff..42ab219c69b 100644 --- a/ace/Event_Handler.h +++ b/ace/Event_Handler.h @@ -151,6 +151,24 @@ protected: ACE_Proactor *proactor_; }; +struct ACE_Export ACE_Notification_Buffer + // = TITLE + // Simple wrapper for passing <ACE_Event_Handler *>s and + // <ACE_Reactor_Mask>s between threads. +{ + ACE_Notification_Buffer (void); + + ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + + ACE_Event_Handler *eh_; + // Pointer to the Event_Handler that will be dispatched + // by the main event loop. + + ACE_Reactor_Mask mask_; + // Mask that indicates which method to call. +}; + #if defined (__ACE_INLINE__) #include "ace/Event_Handler.i" #endif /* __ACE_INLINE__ */ diff --git a/ace/Memory_Pool.cpp b/ace/Memory_Pool.cpp index aebceed532a..dc4cd4ffb4d 100644 --- a/ace/Memory_Pool.cpp +++ b/ace/Memory_Pool.cpp @@ -1,4 +1,3 @@ - // $Id$ // Memory_Pool.cpp @@ -102,7 +101,7 @@ ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot) return ACE_OS::mprotect (addr, len, prot); } -ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const char *pool_name, +ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const char *backing_store_name, const OPTIONS *options) : base_addr_ (0), flags_ (MAP_SHARED), @@ -121,25 +120,25 @@ ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const char *pool_name, this->write_each_page_ = options->write_each_page_; } - if (pool_name == 0) + if (backing_store_name == 0) // Only create a new unique filename for the backing store file // if the user didn't supply one... - pool_name = ACE_DEFAULT_BACKING_STORE; // from "ace/OS.h" + backing_store_name = ACE_DEFAULT_BACKING_STORE; // from "ace/OS.h" - ACE_OS::strncpy (this->backing_store_, pool_name, - sizeof this->backing_store_); + ACE_OS::strncpy (this->backing_store_name_, backing_store_name, + sizeof this->backing_store_name_); if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) - ACE_ERROR ((LM_ERROR, "%p\n", this->backing_store_)); + ACE_ERROR ((LM_ERROR, "%p\n", this->backing_store_name_)); } // Compute the new file_offset of the backing store and commit the // memory. int -ACE_MMAP_Memory_Pool::commit_backing_store (size_t rounded_bytes, +ACE_MMAP_Memory_Pool::commit_backing_store_name (size_t rounded_bytes, off_t &file_offset) { - ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store"); + ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store_name"); size_t seek_len; @@ -162,7 +161,7 @@ ACE_MMAP_Memory_Pool::commit_backing_store (size_t rounded_bytes, file_offset = ACE_OS::lseek (this->mmap_.handle () , seek_len - 1, SEEK_END); if (file_offset == -1 || ACE_OS::write (this->mmap_.handle (), "", 1) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", this->backing_store_), -1); + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", this->backing_store_name_), -1); } // Increment by one to put us at the beginning of the next chunk... @@ -187,7 +186,7 @@ ACE_MMAP_Memory_Pool::map_file (off_t file_offset) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) base_addr = %u, addr = %u, file_offset = %u, %p\n", this->mmap_.addr (), this->base_addr_, - file_offset, this->backing_store_), -1); + file_offset, this->backing_store_name_), -1); return 0; } @@ -208,7 +207,7 @@ ACE_MMAP_Memory_Pool::acquire (size_t nbytes, off_t file_offset; - if (this->commit_backing_store (rounded_bytes, file_offset) == -1) + if (this->commit_backing_store_name (rounded_bytes, file_offset) == -1) return 0; if (this->map_file (file_offset) == -1) @@ -232,7 +231,7 @@ ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes, first_time = 0; - if (this->mmap_.open (this->backing_store_, + if (this->mmap_.open (this->backing_store_name_, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, ACE_DEFAULT_FILE_PERMS) != -1) { @@ -244,7 +243,7 @@ ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes, { errno = 0; // Reopen file *without* using O_EXCL... - if (this->mmap_.map (this->backing_store_, + if (this->mmap_.map (this->backing_store_name_, -1, O_RDWR, ACE_DEFAULT_FILE_PERMS, @@ -276,6 +275,16 @@ ACE_MMAP_Memory_Pool::remap (void *addr) return this->map_file (current_file_offset); } +ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options (const char *base_addr, + int use_fixed_addr, + int write_each_page) + : base_addr_ (base_addr), + use_fixed_addr_ (use_fixed_addr), + write_each_page_ (write_each_page) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options"); +} + // Handle SIGSEGV and SIGBUS signals to remap memory properly. When a // process reads or writes to non-mapped memory a signal (SIGBUS or // SIGSEGV) will be triggered. At that point, the ACE_Sig_Handler @@ -321,9 +330,9 @@ ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool) -ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const char *pool_name, +ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const char *backing_store_name, const OPTIONS *options) - : ACE_MMAP_Memory_Pool (pool_name, options) + : ACE_MMAP_Memory_Pool (backing_store_name, options) { ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool"); } @@ -379,6 +388,16 @@ ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool (const char *, #if !defined (ACE_LACKS_SYSV_SHMEM) ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool) +ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options (const char *base_addr, + size_t max_segments, + size_t file_perms) + : base_addr_ (base_addr), + max_segments_ (max_segments), + file_perms_ (file_perms) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options"); +} + void ACE_Shared_Memory_Pool::dump (void) const { @@ -390,15 +409,15 @@ ACE_Shared_Memory_Pool::in_use (off_t &offset, int &counter) { offset = 0; - SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + SHM_TABLE *st = (SHM_TABLE *) this->base_addr_; shmid_ds buf; for (counter = 0; - counter < ACE_DEFAULT_MAX_SEGMENTS - && st[counter].used == 1; + counter < this->max_segments_ + && st[counter].used_ == 1; counter++) { - if (ACE_OS::shmctl (st[counter].shmid, IPC_STAT, &buf) == -1) + if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmctl"), -1); offset += buf.shm_segsz; // ACE_DEBUG ((LM_DEBUG, "(%P|%t) segment size = %d, offset = %d\n", buf.shm_segsz, offset)); @@ -408,39 +427,38 @@ ACE_Shared_Memory_Pool::in_use (off_t &offset, } int -ACE_Shared_Memory_Pool::commit_backing_store (size_t rounded_bytes, - off_t &offset) +ACE_Shared_Memory_Pool::commit_backing_store_name (size_t rounded_bytes, + off_t &offset) { ACE_TRACE ("ACE_Shared_Memory_Pool::update"); int counter; - SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + SHM_TABLE *st = (SHM_TABLE *) this->base_addr_; if (this->in_use (offset, counter) == -1) return -1; - if (counter == ACE_DEFAULT_MAX_SEGMENTS) + if (counter == this->max_segments_) ACE_ERROR_RETURN ((LM_ERROR, "exceeded max number of segments = %d, base = %u, offset = %u\n", - counter, ACE_DEFAULT_BASE_ADDR, offset), -1); + counter, this->base_addr_, offset), -1); else { - int shmid = ACE_OS::shmget (st[counter].key, + int shmid = ACE_OS::shmget (st[counter].key_, rounded_bytes, - ACE_DEFAULT_FILE_PERMS | IPC_CREAT | IPC_EXCL); + this->file_perms_ | IPC_CREAT | IPC_EXCL); if (shmid == -1) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmget"), 0); - st[counter].shmid = shmid; - st[counter].used = 1; + st[counter].shmid_ = shmid; + st[counter].used_ = 1; - void *address = (void *) (ACE_DEFAULT_BASE_ADDR + offset); - void *shmem = ACE_OS::shmat (st[counter].shmid, (char *) address, 0); + void *address = (void *) (((char *) this->base_addr_) + offset); + void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0); if (shmem != address) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, address = %u\n", "shmat", shmem, address), 0); } - return 0; } @@ -464,22 +482,39 @@ ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *) if (this->in_use (offset, counter) == -1) ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "in_use")); else if (!(siginfo->si_code == SEGV_MAPERR - && siginfo->si_addr < (((char *) ACE_DEFAULT_BASE_ADDR) + offset) - && siginfo->si_addr >= ((char *) ACE_DEFAULT_BASE_ADDR))) + && siginfo->si_addr < (((char *) this->base_addr_) + offset) + && siginfo->si_addr >= ((char *) this->base_addr_))) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) address %u out of range\n", siginfo->si_addr), -1); } #endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */ - this->commit_backing_store (this->round_up (ACE_DEFAULT_SEGMENT_SIZE), - offset); + this->commit_backing_store_name (this->round_up (ACE_DEFAULT_SEGMENT_SIZE), + offset); return 0; } -ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const char *, - const OPTIONS *) +ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const char *backing_store_name, + const OPTIONS *options) + : base_addr_ (0), + file_perms_ (ACE_DEFAULT_FILE_PERMS), + max_segments_ (ACE_DEFAULT_MAX_SEGMENTS) { ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool"); + // Only change the defaults if <options> != 0. + if (options) + { + this->base_addr_ = (void *) options->base_addr_; + this->max_segments_ = options->max_segments_; + this->file_perms_ = options->file_perms_; + } + + if (backing_store_name) + // Convert the string into a number that is used as the segment key. + ::sscanf (backing_store_name, "%d", &this->base_shm_key_); + else + this->base_shm_key_ = ACE_DEFAULT_SHM_KEY; + if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Sig_Handler::register_handler")); } @@ -498,11 +533,11 @@ ACE_Shared_Memory_Pool::acquire (size_t nbytes, off_t offset; - if (this->commit_backing_store (rounded_bytes, offset) == -1) + if (this->commit_backing_store_name (rounded_bytes, offset) == -1) return 0; // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); - return ((char *) ACE_DEFAULT_BASE_ADDR) + offset; + return ((char *) this->base_addr_) + offset; } // Ask system for initial chunk of shared memory. @@ -515,16 +550,15 @@ ACE_Shared_Memory_Pool::init_acquire (size_t nbytes, ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire"); int counter; - void *base_addr = (void *) ACE_DEFAULT_BASE_ADDR; off_t shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE)); rounded_bytes = this->round_up (nbytes); // Acquire the semaphore to serialize initialization and prevent // race conditions. - int shmid = ACE_OS::shmget (ACE_DEFAULT_SHM_KEY, + int shmid = ACE_OS::shmget (this->base_shm_key_, rounded_bytes + shm_table_offset, - ACE_DEFAULT_FILE_PERMS | IPC_CREAT | IPC_EXCL); + this->file_perms_ | IPC_CREAT | IPC_EXCL); if (shmid == -1) { if (errno != EEXIST) @@ -532,44 +566,46 @@ ACE_Shared_Memory_Pool::init_acquire (size_t nbytes, first_time = 0; - shmid = ACE_OS::shmget (ACE_DEFAULT_SHM_KEY, 0, 0); + shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0); if (shmid == -1) ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmget"), 0); - void *shmem = ACE_OS::shmat (shmid, (char *) base_addr, 0); + // This implementation doesn't care if we don't get the key we want... + this->base_addr_ = ACE_OS::shmat (shmid, (char *) this->base_addr_, 0); - if (shmem != base_addr) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, base_addr = %u\n", - "shmat", shmem, base_addr), 0); + if (this->base_addr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, base_addr = %u\n", + "shmat", this->base_addr_), 0); } else { first_time = 1; - void *shmem = ACE_OS::shmat (shmid, (char *) base_addr, 0); + // This implementation doesn't care if we don't get the key we want... + this->base_addr_ = ACE_OS::shmat (shmid, (char *) this->base_addr_, 0); - if (shmem != base_addr) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, base_addr = %u\n", - "shmat", shmem, base_addr), 0); + if (this->base_addr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, base_addr = %u\n", + "shmat", this->base_addr_), 0); - SHM_TABLE *st = (SHM_TABLE *) base_addr; + SHM_TABLE *st = (SHM_TABLE *) this->base_addr_; - st[0].key = ACE_DEFAULT_SHM_KEY; - st[0].shmid = shmid; - st[0].used = 1; + st[0].key_ = this->base_shm_key_; + st[0].shmid_ = shmid; + st[0].used_ = 1; for (counter = 1; // Skip over the first entry... - counter < ACE_DEFAULT_MAX_SEGMENTS; + counter < this->max_segments_; counter++) { - st[counter].key = ACE_DEFAULT_SHM_KEY + counter; - st[counter].shmid = 0; - st[counter].used = 0; + st[counter].key_ = this->base_shm_key_ + counter; + st[counter].shmid_ = 0; + st[counter].used_ = 0; } } - return (void *) (((char *) base_addr) + shm_table_offset); + return (void *) (((char *) this->base_addr_) + shm_table_offset); } // Instruct the memory pool to release all of its resources. @@ -580,12 +616,12 @@ ACE_Shared_Memory_Pool::release (void) ACE_TRACE ("ACE_Shared_Memory_Pool::release"); int result = 0; - SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + SHM_TABLE *st = (SHM_TABLE *) this->base_addr_; for (int counter = 0; - counter < ACE_DEFAULT_MAX_SEGMENTS && st[counter].used == 1; + counter < this->max_segments_ && st[counter].used_ == 1; counter++) - if (ACE_OS::shmctl (st[counter].shmid, IPC_RMID, NULL) == -1) + if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, NULL) == -1) result = -1; return result; diff --git a/ace/Memory_Pool.h b/ace/Memory_Pool.h index 1918970efcd..bd60596415d 100644 --- a/ace/Memory_Pool.h +++ b/ace/Memory_Pool.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY @@ -34,7 +33,8 @@ class ACE_Export ACE_Sbrk_Memory_Pool_Options // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. -{}; +{ +}; class ACE_Export ACE_Sbrk_Memory_Pool // = TITLE @@ -43,7 +43,7 @@ class ACE_Export ACE_Sbrk_Memory_Pool public: typedef ACE_Sbrk_Memory_Pool_Options OPTIONS; - ACE_Sbrk_Memory_Pool (const char *pool_name = 0, + ACE_Sbrk_Memory_Pool (const char *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. @@ -101,7 +101,22 @@ class ACE_Export ACE_Shared_Memory_Pool_Options // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. -{}; +{ +public: + // = Initialization method. + ACE_Shared_Memory_Pool_Options (const char *base_addr = ACE_DEFAULT_BASE_ADDR, + size_t max_segments = ACE_DEFAULT_MAX_SEGMENTS, + size_t file_perms = ACE_DEFAULT_FILE_PERMS); + + const char *base_addr_; + // Base address of the memory-mapped backing store. + + size_t max_segments_; + // Number of shared memory segments to allocate. + + size_t file_perms_; + // File permissions to use when creating/opening a segment. +}; class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler // = TITLE @@ -112,7 +127,7 @@ class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler public: typedef ACE_Shared_Memory_Pool_Options OPTIONS; - ACE_Shared_Memory_Pool (const char *pool_name = ACE_ITOA (ACE_DEFAULT_SHM_KEY), + ACE_Shared_Memory_Pool (const char *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. @@ -158,19 +173,40 @@ protected: // Implement the algorithm for rounding up the request to an // appropriate chunksize. - virtual int commit_backing_store (size_t rounded_bytes, + virtual int commit_backing_store_name (size_t rounded_bytes, off_t &offset); // Commits a new shared memory segment if necessary after an // acquire() or a signal. <offset> is set to the new offset into // the backing store. + // = Keeps track of all the segments being used. struct SHM_TABLE { - key_t key; - int shmid; - int used; + key_t key_; + // Shared memory segment key. + + int shmid_; + // Shared memory segment internal id. + + int used_; + // Is the segment currently used.; }; + void *base_addr_; + // Base address of the shared memory segment. If this has the value + // of 0 then the OS is free to select any address, otherwise this + // value is what the OS must try to use to map the shared memory + // segment. + + size_t file_perms_; + // File permissions to use when creating/opening a segment. + + size_t max_segments_; + // Number of shared memory segments in the <SHM_TABLE> table. + + key_t base_shm_key_; + // Base shared memory key for the segment. + virtual int in_use (off_t &offset, int &counter); // Determine how much memory is currently in use. @@ -180,9 +216,6 @@ protected: virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); // Handle SIGSEGV and SIGBUS signals to remap shared memory // properly. - - ACE_SV_Semaphore_Complex init_finished_; - // Used to serialize initialization of the Memory_Pool and Malloc. }; #endif /* !ACE_LACKS_SYSV_SHMEM */ @@ -204,7 +237,7 @@ class ACE_Export ACE_Local_Memory_Pool public: typedef ACE_Local_Memory_Pool_Options OPTIONS; - ACE_Local_Memory_Pool (const char *pool_name = 0, + ACE_Local_Memory_Pool (const char *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. @@ -261,16 +294,20 @@ class ACE_Export ACE_MMAP_Memory_Pool_Options // compilers. { public: + // = Initialization method. ACE_MMAP_Memory_Pool_Options (const char *base_addr = ACE_DEFAULT_BASE_ADDR, int use_fixed_addr = 1, - int write_each_page = 1) - : base_addr_ (base_addr), - use_fixed_addr_ (use_fixed_addr), - write_each_page_ (write_each_page) {} + int write_each_page = 1); const char *base_addr_; + // Base address of the memory-mapped backing store. + int use_fixed_addr_; + // Must we use the <base_addr_> or can we let mmap(2) select it? + int write_each_page_; + // Should each page be written eagerly to avoid surprises later + // on? }; class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler @@ -283,7 +320,7 @@ public: // = Initialization and termination methods. - ACE_MMAP_Memory_Pool (const char *pool_name = 0, + ACE_MMAP_Memory_Pool (const char *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. @@ -340,7 +377,7 @@ protected: virtual size_t round_up (size_t nbytes); - virtual int commit_backing_store (size_t rounded_bytes, off_t &file_offset); + virtual int commit_backing_store_name (size_t rounded_bytes, off_t &file_offset); // Compute the new file_offset of the backing store and commit the // memory. @@ -369,8 +406,8 @@ protected: // Should we write a byte to each page to forceably allocate memory // for this backing store? - char backing_store_[MAXPATHLEN]; - // Name of the backing store where the shared memory is kept. + char backing_store_name_[MAXPATHLEN]; + // Name of the backing store where the shared memory pool is kept. }; class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool @@ -388,7 +425,7 @@ class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool public: // = Initialization and termination methods. - ACE_Lite_MMAP_Memory_Pool (const char *pool_name = 0, + ACE_Lite_MMAP_Memory_Pool (const char *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. diff --git a/ace/Message_Queue.cpp b/ace/Message_Queue.cpp index 20d528dd1f6..4cd30b68f32 100644 --- a/ace/Message_Queue.cpp +++ b/ace/Message_Queue.cpp @@ -38,12 +38,14 @@ ACE_Message_Queue<ACE_SYNCH_2>::dump (void) const template <ACE_SYNCH_1> ACE_Message_Queue<ACE_SYNCH_2>::ACE_Message_Queue (size_t hwm, - size_t lwm) + size_t lwm, + ACE_Notification_Strategy *ns) : notempty_cond_ (this->lock_), notfull_cond_ (this->lock_) { ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::ACE_Message_Queue"); - if (this->open (hwm, lwm) == -1) + + if (this->open (hwm, lwm, ns) == -1) ACE_ERROR ((LM_ERROR, "open")); } @@ -51,9 +53,8 @@ template <ACE_SYNCH_1> ACE_Message_Queue<ACE_SYNCH_2>::~ACE_Message_Queue (void) { ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::~ACE_Message_Queue"); - if (this->head_ != 0) - if (this->close () == -1) - ACE_ERROR ((LM_ERROR, "close")); + if (this->head_ != 0 && this->close () == -1) + ACE_ERROR ((LM_ERROR, "close")); } // Don't bother locking since if someone calls this function more than @@ -61,16 +62,20 @@ ACE_Message_Queue<ACE_SYNCH_2>::~ACE_Message_Queue (void) // concurrency control! template <ACE_SYNCH_1> int -ACE_Message_Queue<ACE_SYNCH_2>::open (size_t hwm, size_t lwm) +ACE_Message_Queue<ACE_SYNCH_2>::open (size_t hwm, + size_t lwm, + ACE_Notification_Strategy *ns) { ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::open"); this->high_water_mark_ = hwm; this->low_water_mark_ = lwm; - this->deactivated_ = 0; - this->cur_bytes_ = 0; - this->cur_count_ = 0; - this->tail_ = 0; - this->head_ = 0; + this->deactivated_ = 0; + this->cur_bytes_ = 0; + this->cur_count_ = 0; + this->tail_ = 0; + this->head_ = 0; + + this->notification_strategy_ = ns; return 0; } @@ -130,6 +135,9 @@ ACE_Message_Queue<ACE_SYNCH_2>::close (void) delete temp; } + if (this->delete_notification_strategy_) + delete this->delete_notification_strategy_; + return res; } @@ -370,29 +378,40 @@ ACE_Message_Queue<ACE_SYNCH_2>::enqueue_head (ACE_Message_Block *new_item, ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::enqueue_head"); ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); - if (this->deactivated_) + int queue_count; + { + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + + queue_count = this->enqueue_head_i (new_item); + } + if (queue_count == -1) + return -1; + else { - errno = ESHUTDOWN; - return -1; + this->notify (); + return queue_count; } - - // Wait while the queue is full - - while (this->is_full_i ()) - { - if (this->notfull_cond_.wait (tv) == -1) - { - if (errno == ETIME) - errno = EWOULDBLOCK; - return -1; - } - if (this->deactivated_) - { - errno = ESHUTDOWN; - return -1; - } - } - return this->enqueue_head_i (new_item); } // Enqueue an <ACE_Message_Block *> into the <Message_Queue> in @@ -400,37 +419,48 @@ ACE_Message_Queue<ACE_SYNCH_2>::enqueue_head (ACE_Message_Block *new_item, // -1 on failure, else the number of items still on the queue. template <ACE_SYNCH_1> int -ACE_Message_Queue<ACE_SYNCH_2>::enqueue (ACE_Message_Block *new_item, - ACE_Time_Value *tv) +ACE_Message_Queue<ACE_SYNCH_2>::enqueue_prio (ACE_Message_Block *new_item, + ACE_Time_Value *tv) { ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::enqueue"); - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); - - if (this->deactivated_) - { - errno = ESHUTDOWN; - return -1; - } - - // Wait while the queue is full - - while (this->is_full_i ()) + int queue_count; + + { + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + + queue_count = this->enqueue_i (new_item); + } + if (queue_count == -1) + return -1; + else { - if (this->notfull_cond_.wait (tv) == -1) - { - if (errno == ETIME) - errno = EWOULDBLOCK; - return -1; - } - if (this->deactivated_) - { - errno = ESHUTDOWN; - return -1; - } + this->notify (); + return queue_count; } - - return this->enqueue_i (new_item); } // Block indefinitely waiting for an item to arrive, @@ -441,31 +471,42 @@ ACE_Message_Queue<ACE_SYNCH_2>::enqueue_tail (ACE_Message_Block *new_item, ACE_Time_Value *tv) { ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::enqueue_tail"); - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); - if (this->deactivated_) - { - errno = ESHUTDOWN; - return -1; - } - - // Wait while the queue is full - - while (this->is_full_i ()) + int queue_count; + { + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + queue_count = this->enqueue_tail_i (new_item); + } + if (queue_count == -1) + return -1; + else { - if (this->notfull_cond_.wait (tv) == -1) - { - if (errno == ETIME) - errno = EWOULDBLOCK; - return -1; - } - if (this->deactivated_) - { - errno = ESHUTDOWN; - return -1; - } + this->notify (); + return queue_count; } - return this->enqueue_tail_i (new_item); } // Remove an item from the front of the queue. If TV == 0 block @@ -505,4 +546,16 @@ ACE_Message_Queue<ACE_SYNCH_2>::dequeue_head (ACE_Message_Block *&first_item, return this->dequeue_head_i (first_item); } +template <ACE_SYNCH_1> int +ACE_Message_Queue<ACE_SYNCH_2>::notify (void) +{ + ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::dequeue_head"); + + // By default, don't do anything. + if (this->notification_strategy_ == 0) + return 0; + else + return this->notification_strategy_->notify (); +} + #endif /* ACE_MESSAGE_QUEUE_C */ diff --git a/ace/Message_Queue.h b/ace/Message_Queue.h index 73fa40f3108..fc5be17ea6f 100644 --- a/ace/Message_Queue.h +++ b/ace/Message_Queue.h @@ -19,6 +19,7 @@ #include "ace/Message_Block.h" #include "ace/Time_Value.h" +#include "ace/Strategies.h" #include "ace/IO_Cntl_Msg.h" // Forward decl. @@ -64,15 +65,19 @@ public: // = Initialization and termination methods. ACE_Message_Queue (size_t hwm = DEFAULT_HWM, - size_t lwm = DEFAULT_LWM); + size_t lwm = DEFAULT_LWM, + ACE_Notification_Strategy * = 0); + // Create a message queue with all the defaults. - int open (size_t hwm = DEFAULT_HWM, size_t lwm = DEFAULT_LWM); + int open (size_t hwm = DEFAULT_HWM, + size_t lwm = DEFAULT_LWM, + ACE_Notification_Strategy * = 0); // Create a message queue with all the defaults. int close (void); // Close down the message queue and release all resources. - ~ACE_Message_Queue (void); + virtual ~ACE_Message_Queue (void); // Close down the message queue and release all resources. int peek_dequeue_head (ACE_Message_Block *&first_item, @@ -83,7 +88,7 @@ public: // = For all the following three routines if tv == 0, the caller will block until action is possible, else will wait until the absolute time specified in *tv elapses). Calls will return, however, when queue is closed, deactivated, when a signal occurs, or if the time specified in tv elapses, (in which case errno = EWOULDBLOCK). - int enqueue (ACE_Message_Block *new_item, ACE_Time_Value *tv = 0); + int enqueue_prio (ACE_Message_Block *new_item, ACE_Time_Value *tv = 0); // Enqueue an <ACE_Message_Block *> into the <Message_Queue> in // accordance with its <msg_priority> (0 is lowest priority). FIFO // order is maintained when messages of the same priority are @@ -144,6 +149,20 @@ public: // before the call and WAS_ACTIVE if queue was active before the // call. + virtual int notify (void); + // This hook is automatically invoked by <enqueue_head>, + // <enqueue_tail>, and <enqueue_prio> when a new item is inserted + // into the queue. Subclasses can override this method to perform + // specific notification strategies (e.g., signaling events for a + // <ReactorEx>, notifying a <Reactor>, etc.). In a multi-threaded + // application with concurrent consumers, there is no guarantee that + // the queue will be still be non-empty by the time the notification + // occurs. + + // = Get/set the notification strategy for the <Message_Queue> + ACE_Notification_Strategy *notification_strategy (void); + void notification_strategy (ACE_Notification_Strategy *s); + void dump (void) const; // Dump the state of an object. @@ -151,7 +170,9 @@ public: // Declare the dynamic allocation hooks. protected: - // = Routines that actually do the enqueueing and dequeueing (these assume that locks are held by the corresponding public methods). + // = Routines that actually do the enqueueing and dequeueing. + // These routines assume that locks are held by the corresponding + // public methods. int enqueue_i (ACE_Message_Block *new_item); // Enqueue an <ACE_Message_Block *> in accordance with its priority. @@ -199,6 +220,9 @@ protected: int deactivated_; // Indicates that the queue is inactive. + ACE_Notification_Strategy *notification_strategy_; + // The notification strategy used when a new message is enqueued. + // = Synchronization primitives for controlling concurrent access. ACE_SYNCH_MUTEX lock_; // Protect queue from concurrent access. diff --git a/ace/Message_Queue.i b/ace/Message_Queue.i index 7661fb826c7..73bdb402b8f 100644 --- a/ace/Message_Queue.i +++ b/ace/Message_Queue.i @@ -3,6 +3,22 @@ // Message_Queue.i +template <ACE_SYNCH_1> ACE_INLINE ACE_Notification_Strategy * +ACE_Message_Queue<ACE_SYNCH_2>::notification_strategy (void) +{ + ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::notification_strategy"); + + return this->notification_strategy_; +} + +template <ACE_SYNCH_1> ACE_INLINE void +ACE_Message_Queue<ACE_SYNCH_2>::notification_strategy (ACE_Notification_Strategy *s) +{ + ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::notification_strategy"); + + this->notification_strategy_ = s; +} + // Check if queue is empty (does not hold locks). template <ACE_SYNCH_1> ACE_INLINE int @@ -1786,7 +1786,7 @@ typedef LPCTSTR ACE_DL_TYPE; #endif /* ACE_HAS_CHARPTR_DL */ #if !defined (ACE_HAS_SIGINFO_T) -struct siginfo_t +struct ACE_Export siginfo_t { siginfo_t (ACE_HANDLE handle); diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp index 30b8a5b868d..e654a1d2333 100644 --- a/ace/Reactor.cpp +++ b/ace/Reactor.cpp @@ -9,30 +9,6 @@ ACE_ALLOC_HOOK_DEFINE(ACE_Reactor) -struct ACE_Notification_Buffer -{ - ACE_Notification_Buffer (void); - - ACE_Notification_Buffer (ACE_Event_Handler *eh, - ACE_Reactor_Mask mask); - - ACE_Event_Handler *eh_; - // Pointer to the Event_Handler that will be dispatched - // by the main event loop. - - ACE_Reactor_Mask mask_; - // Mask that indicates which method to call. -}; - -ACE_Notification_Buffer::ACE_Notification_Buffer (void) {} - -ACE_Notification_Buffer::ACE_Notification_Buffer (ACE_Event_Handler *eh, - ACE_Reactor_Mask mask) - : eh_ (eh), - mask_ (mask) -{ -} - // Performs sanity checking on the ACE_HANDLE. int @@ -586,7 +562,8 @@ ACE_Notification_Handler::notify (ACE_Event_Handler *eh, sizeof buffer); if (n == -1) return -1; - return 0; + else + return 0; } // Handles pending threads (if any) that are waiting to unblock the diff --git a/ace/ReactorEx.cpp b/ace/ReactorEx.cpp index a375c073e66..73fd659cee0 100644 --- a/ace/ReactorEx.cpp +++ b/ace/ReactorEx.cpp @@ -24,11 +24,10 @@ ACE_ReactorEx::~ACE_ReactorEx (void) } int -ACE_ReactorEx::notify (void) +ACE_ReactorEx::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); { - ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); - - return notify_handler_.notify (); + return notify_handler_.notify (eh, mask); } int @@ -116,10 +115,20 @@ int ACE_ReactorEx::handle_events (ACE_Time_Value *how_long, int wait_all) { + ACE_TRACE ("ACE_ReactorEx::handle_events"); + // @@ Need to implement -wait_all-. + // Tim, is this the right place for the token lock? + ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); + + // Tim, this function is too long. It should be broken up into + // another several methods (e.g., wait_for_multi_events() and + // dispatch(), just like the ACE_Reactor. + DWORD wait_status; int handles_skipped = 0; + // These relative_things are moved through the handles_ each time // handle_events is called. Set relative index = -1 so we can check // in case of timeouts. @@ -260,33 +269,105 @@ ACE_ReactorEx_Token::sleep_hook (void) ACE_ReactorEx_Notify::ACE_ReactorEx_Notify (void) { - // Create an "auto-reset" event that is used to unblock the - // ReactorEx. - handle_ = ::CreateEvent (NULL, FALSE, FALSE, NULL); } ACE_ReactorEx_Notify::~ACE_ReactorEx_Notify (void) { - ACE_OS::close (handle_); } ACE_HANDLE ACE_ReactorEx_Notify::get_handle (void) const { - return this->handle_; + return this->notify_event_.handle (); } +// Handle all pending notifications. + int -ACE_ReactorEx_Notify::handle_signal (int signum, siginfo_t *, ucontext_t *) +ACE_ReactorEx_Notify::handle_signal (int signum, + siginfo_t *siginfo, + ucontext_t *) { - // Do nothing. - return 0; + // Just check for sanity... + if (siginfo->si_handle_ != this->notify_event_.handle ()) + return -1; + + for (;;) + { + ACE_Message_Block *mb = 0; + + if (this->message_queue_.dequeue_head (mb) == -1) + { + if (errno == EWOULDBLOCK) + // We've reached the end of the processing, return + // normally. + return 0; + else + return -1; // Something weird happened... + } + else + { + ACE_Notification_Buffer *buffer = + (ACE_Notification_Buffer *) mb->base (); + + // If eh == 0 then we've got major problems! Otherwise, we need + // to dispatch the appropriate handle_* method on the + // ACE_Event_Handler pointer we've been passed. + if (buffer->eh_ != 0) + { + int result = 0; + + switch (buffer->mask_) + { + case ACE_Event_Handler::READ_MASK: + result = buffer->eh_->handle_input (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::WRITE_MASK: + result = buffer->eh_->handle_output (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::EXCEPT_MASK: + result = buffer->eh_->handle_exception (ACE_INVALID_HANDLE); + break; + default: + ACE_ERROR ((LM_ERROR, "invalid mask = %d\n", buffer->mask_)); + break; + } + if (result == -1) + buffer->eh_->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::EXCEPT_MASK); + } + // Make sure to delete the memory regardless of success or + // failure! + delete mb; + } + } } +// Notify the ReactorEx, potentially enqueueing the +// <ACE_Event_Handler> for subsequent processing in the ReactorEx +// thread of control. + int -ACE_ReactorEx_Notify::notify (void) +ACE_ReactorEx_Notify::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) { - return ::SetEvent (handle_) ? 0 : -1; + if (eh != 0) + { + ACE_Message_Block *mb = 0; + ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof ACE_Notification_Buffer), -1); + + ACE_Notification_Buffer *buffer = (ACE_Notification_Buffer *) mb->base (); + buffer->eh_ = eh; + buffer->mask_ = mask; + + if (this->message_queue_.enqueue_tail (mb) == -1) + { + delete mb; + return -1; + } + } + + return this->notify_event_.signal (); } #endif /* ACE_WIN32 */ diff --git a/ace/ReactorEx.h b/ace/ReactorEx.h index 18c2e0a0be0..d25fa3e314e 100644 --- a/ace/ReactorEx.h +++ b/ace/ReactorEx.h @@ -17,9 +17,9 @@ #if !defined (ACE_ReactorEx_H) #define ACE_ReactorEx_H -#include "ace/Timer_Queue.h" #include "ace/Time_Value.h" #include "ace/Event_Handler.h" +#include "ace/Message_Queue.h" #include "ace/Token.h" #if defined (ACE_MT_SAFE) @@ -72,18 +72,33 @@ public: ~ACE_ReactorEx_Notify (void); // Destroys a handle. - int notify (void); - // Signals a handle. + int notify (ACE_Event_Handler *eh = 0, + ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK); + // Special trick to unblock WaitForMultipleObjects() when updates + // occur in somewhere other than the main <ACE_ReactorEx> thread. + // All we do is enqueue <eh> and <mask> onto the <ACE_Message_Queue> + // and wakeup the ReactorEx by signaling its <ACE_Event> handle. private: + struct + { + ACE_Event_Handler *eh_; + ACE_Reactor_Mask mask_; + }; + virtual ACE_HANDLE get_handle (void) const; // Returns a handle. virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); - // Does nothing with a handle. + // Does with a handle. - ACE_HANDLE handle_; + ACE_Auto_Event notify_event_; // A handle. + + ACE_Message_Queue<ACE_MT_SYNCH> message_queue_; + // Message queue that keeps track of pending <ACE_Event_Handlers>. + // This queue must be thread-safe because it can be called by + // multiple threads of control. }; class ACE_Export ACE_ReactorEx @@ -140,9 +155,10 @@ public: // -mask- == ACE_Event_Handler::DONT_CALL then the -handle_close- // method of the -eh- is not invoked. - virtual int notify (void); - // Wakeup ACE_ReactorEx if currently blocked - // WaitForMultipleObjects. + int notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK); + // Wakeup <ACE_ReactorEx> if currently blocked in + // WaitForMultipleObjects(). // = Timer management. virtual int schedule_timer (ACE_Event_Handler *eh, @@ -219,7 +235,9 @@ class ACE_Export ACE_ReactorEx public: virtual int handle_events (void) { return -1; } virtual int handle_events (ACE_Time_Value &) { return -1; } - virtual int notify (void) { return 0; } + int notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK) + { return 0; } }; #endif /* ACE_WIN32 */ diff --git a/ace/SV_Semaphore_Complex.cpp b/ace/SV_Semaphore_Complex.cpp index 776907705f3..836a0cbabf2 100644 --- a/ace/SV_Semaphore_Complex.cpp +++ b/ace/SV_Semaphore_Complex.cpp @@ -138,7 +138,7 @@ ACE_SV_Semaphore_Complex::open (key_t k, // Decrement the process counter. We don't need a lock to do this. if (ACE_OS::semop (this->internal_id_, - &ACE_SV_Semaphore_Complex::op_open_[0], 1) < 0) + &ACE_SV_Semaphore_Complex::op_open_[0], 1) < 0) return this->init (); return 0; } @@ -219,8 +219,15 @@ ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (const char *name, int perms) { ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex"); - if (this->open (ACE_SV_Semaphore_Simple::name_2_key (name), - flags, initial_value, nsems, perms) == -1) + + key_t key; + + if (name == 0) + key = ACE_DEFAULT_SEM_KEY; + else + key = this->name_2_key (name); + + if (this->open (key, flags, initial_value, nsems, perms) == -1) ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SV_Semaphore_Complex")); } @@ -236,4 +243,3 @@ ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (void) ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex"); this->init (); } - diff --git a/ace/SV_Semaphore_Simple.cpp b/ace/SV_Semaphore_Simple.cpp index bc4e92787d8..e593d4cb36b 100644 --- a/ace/SV_Semaphore_Simple.cpp +++ b/ace/SV_Semaphore_Simple.cpp @@ -154,8 +154,15 @@ ACE_SV_Semaphore_Simple::open (const char *name, int perms) { ACE_TRACE ("ACE_SV_Semaphore_Simple::open"); - return this->open (this->name_2_key (name), - flags, initial_value, n, perms); + + key_t key; + + if (name == 0) + key = ACE_DEFAULT_SEM_KEY; + else + key = this->name_2_key (name); + + return this->open (key, flags, initial_value, n, perms); } ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const char *name, @@ -176,3 +183,23 @@ ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple (void) this->close (); } +ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple"); + this->init (); +} + +// Remove all SV_Semaphores associated with a particular key. This +// call is intended to be called from a server, for example, when it +// is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore, +// regardless of whether other processes may be using it or not. Most +// other processes should use close() below. + +int +ACE_SV_Semaphore_Simple::remove (void) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::remove"); + int result = this->control (IPC_RMID); + ((ACE_SV_Semaphore_Simple *) this)->init (); + return result; +} diff --git a/ace/SV_Semaphore_Simple.h b/ace/SV_Semaphore_Simple.h index 76a854eb9ab..04100612e21 100644 --- a/ace/SV_Semaphore_Simple.h +++ b/ace/SV_Semaphore_Simple.h @@ -119,11 +119,11 @@ public: // Declare the dynamic allocation hooks. protected: - key_t key_; - int internal_id_; - int sem_number_; + key_t key_; + int internal_id_; + int sem_number_; - int init (key_t k = ACE_INVALID_SEM_KEY, int i = -1); + int init (key_t k = ACE_INVALID_SEM_KEY, int i = -1); key_t name_2_key (const char *name); // Convert name to key This function is used internally to create // keys for the semaphores. A valid name contains letters and diff --git a/ace/SV_Semaphore_Simple.i b/ace/SV_Semaphore_Simple.i index 1679dd724c6..e4c9fb8d3e1 100644 --- a/ace/SV_Semaphore_Simple.i +++ b/ace/SV_Semaphore_Simple.i @@ -19,21 +19,6 @@ ACE_SV_Semaphore_Simple::control (int cmd, -1 : ACE_OS::semctl (this->internal_id_, semnum, cmd, arg); } -// Remove all SV_Semaphores associated with a particular key. This -// call is intended to be called from a server, for example, when it -// is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore, -// regardless of whether other processes may be using it or not. Most -// other processes should use close() below. - -inline int -ACE_SV_Semaphore_Simple::remove (void) const -{ - ACE_TRACE ("ACE_SV_Semaphore_Simple::remove"); - int result = this->control (IPC_RMID); - ((ACE_SV_Semaphore_Simple *) this)->init (); - return result; -} - // Close a ACE_SV_Semaphore, marking it as invalid for subsequent // operations... @@ -54,13 +39,6 @@ ACE_SV_Semaphore_Simple::op (sembuf op_vec[], int n) const ? -1 : ACE_OS::semop (this->internal_id_, op_vec, n); } -inline -ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (void) -{ - ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple"); - this->init (); -} - // Wait until a ACE_SV_Semaphore's value is greater than 0, the // decrement it by 1 and return. Dijkstra's P operation, Tannenbaums // DOWN operation. diff --git a/ace/Strategies.cpp b/ace/Strategies.cpp index 6fe39d9e29f..197d6cbeb74 100644 --- a/ace/Strategies.cpp +++ b/ace/Strategies.cpp @@ -5,494 +5,38 @@ #define ACE_STRATEGIES_C #define ACE_BUILD_DLL +#include "ace/Reactor.h" +#include "ace/ReactorEx.h" #include "ace/Strategies.h" -ACE_ALLOC_HOOK_DEFINE(ACE_Singleton_Strategy) - -template <class SVC_HANDLER> void -ACE_Singleton_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::dump"); -} - -template <class SVC_HANDLER> int -ACE_Singleton_Strategy<SVC_HANDLER>::open (SVC_HANDLER *sh, - ACE_Thread_Manager *) -{ - ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::open"); - if (this->svc_handler_ != 0) - delete this->svc_handler_; - - this->svc_handler_ = sh; - return 0; -} - -template <class SVC_HANDLER> -ACE_Singleton_Strategy<SVC_HANDLER>::ACE_Singleton_Strategy (SVC_HANDLER *sh, - ACE_Thread_Manager *tm) - : svc_handler_ (0) -{ - ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::ACE_Singleton_Strategy"); - this->open (sh, tm); -} - -template <class SVC_HANDLER> -ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy (void) -{ - ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy"); - delete this->svc_handler_; -} - -// Create a Singleton SVC_HANDLER by always returning the same -// SVC_HANDLER. - -template <class SVC_HANDLER> SVC_HANDLER * -ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler (void) -{ - ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler"); - return this->svc_handler_; -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy) - -template <class SVC_HANDLER> void -ACE_Creation_Strategy<SVC_HANDLER>::dump (void) const +ACE_Reactor_Notification_Strategy::ACE_Reactor_Notification_Strategy (ACE_Reactor *reactor, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) + : reactor_ (reactor), + eh_ (eh), + mask_ (mask) { - ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::dump"); } -template <class SVC_HANDLER> int -ACE_Creation_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr) +int +ACE_Reactor_Notification_Strategy::notify (void) { - ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::open"); - this->thr_mgr_ = thr_mgr; - return 0; + return this->reactor_->notify (eh, mask); } - -template <class SVC_HANDLER> -ACE_Creation_Strategy<SVC_HANDLER>::ACE_Creation_Strategy (ACE_Thread_Manager *thr_mgr) -{ - ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::ACE_Creation_Strategy"); - this->open (thr_mgr); -} - -// Default behavior is to make a new SVC_HANDLER, passing in the -// Thread_Manager (if any). - -template <class SVC_HANDLER> SVC_HANDLER * -ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler (void) +ACE_ReactorEx_Notification_Strategy::ACE_Reactor_Notification_Strategy (ACE_ReactorEx *reactorex, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) + : reactorex_ (reactorex), + eh_ (eh), + mask_ (mask) { - ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler"); - return new SVC_HANDLER (this->thr_mgr_); } -template <class SVC_HANDLER> -ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy (void) +int +ACE_ReactorEx_Notification_Strategy::notify (void) { - ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy"); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy) - -template <class SVC_HANDLER> void -ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::dump"); -} - -template <class SVC_HANDLER> int -ACE_DLL_Strategy<SVC_HANDLER>::open (const char svc_dll_info[], - ACE_Service_Config *svc_config, - ACE_Thread_Manager *thr_mgr) -{ - ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::open"); - this->inherited::open (thr_mgr); - this->svc_config_ = svc_config; - return 0; -} - -template <class SVC_HANDLER> -ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy (const char svc_dll_info[], - ACE_Service_Config *sc, - ACE_Thread_Manager *thr_mgr) -{ - ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy"); - if (this->open (svc_dll_info, sc, thr_mgr) == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "open")); -} - -template <class SVC_HANDLER> -ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy (void) -{ - ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy"); -} - -// Create a SVC_HANDLER by dynamically linking it from a DLL. - -template <class SVC_HANDLER> SVC_HANDLER * -ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler (void) -{ - ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler"); - // Open the shared library. - void *handle = (void *) ACE_OS::dlopen (this->shared_library_); - - // Extract the factory function. - SVC_HANDLER *(*factory)(void) = (SVC_HANDLER *(*)(void)) ACE_OS::dlsym (handle, - this->factory_function_); - - // Call the factory function to obtain the new SVC_Handler (should - // use RTTI here when it becomes available...) - SVC_HANDLER *svc_handler = (*factory)(); - - if (svc_handler != 0) - { - // Create an ACE_Service_Record containing the SVC_Handler and - // insert into this->svc_config_->svc_rep; - - // @@ This remains to be implemented... - // @@ Somehow, we need to deal with this->thr_mgr_... - } - - return svc_handler; -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Concurrency_Strategy) - -template <class SVC_HANDLER> void -ACE_Concurrency_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::dump"); -} - -// Default behavior is to activate the SVC_HANDLER by calling it's -// open() method, which allows the SVC_HANDLER to determine its own -// concurrency strategy. - -template <class SVC_HANDLER> int -ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg) -{ - ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler"); - // Delegate control to the application-specific service - // handler. - - if (svc_handler->open (arg) == -1) - { - // Close down handler to avoid resource leaks. - svc_handler->close (0); - return -1; - } - else - return 0; -} - -template <class SVC_HANDLER> -ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy (void) -{ - ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy"); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) - -template <class SVC_HANDLER> void -ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::dump"); -} - -template <class SVC_HANDLER> int -ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr, - long thr_flags, - int n_threads) -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::open"); - this->thr_mgr_ = thr_mgr; - this->n_threads_ = n_threads; - this->thr_flags_ = thr_flags; - - // Must have a thread manager! - if (this->thr_mgr_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "error: must have a non-NULL thread manager\n"), -1); - else - return 0; -} - -template <class SVC_HANDLER> -ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy (ACE_Thread_Manager *thr_mgr, - long thr_flags, - int n_threads) -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy"); - this->open (thr_mgr, thr_flags, n_threads); -} - -template <class SVC_HANDLER> -ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy (void) -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy"); -} - -template <class SVC_HANDLER> -ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy (void) -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy"); -} - -template <class SVC_HANDLER> int -ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg) -{ - ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler"); - // Call up to our parent to do the SVC_HANDLER initialization. - if (this->inherited::activate_svc_handler (svc_handler, arg) == -1) - return -1; - else - // Turn the <svc_handler> into an active object (if it isn't - // already one as a result of the first activation...) - return svc_handler->activate (this->thr_flags_, this->n_threads_); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Accept_Strategy) - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy - (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int restart) -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy"); - - if (this->open (local_addr, restart) == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "open")); -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open - (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int restart) -{ - return this->peer_acceptor_.open (local_addr, restart); -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump"); -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy (void) -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy"); -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler - (SVC_HANDLER *svc_handler) -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler"); - - if (this->peer_acceptor_.accept (svc_handler->peer ()) == -1) - { - svc_handler->close (0); - return -1; - } - else - return 0; -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle"); - return this->peer_acceptor_.get_handle (); -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR & -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor"); - return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; -} - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> -ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy (void) -{ - ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy"); - if (this->peer_acceptor_.close () == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "close")); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy) - -template <class SVC_HANDLER> void -ACE_Process_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::dump"); -} - -template <class SVC_HANDLER> int -ACE_Process_Strategy<SVC_HANDLER>::open (int n_processes) -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::open"); - this->n_processes_ = n_processes; - - return 0; -} - -template <class SVC_HANDLER> -ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (int n_processes) -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy"); - this->open (thr_mgr, thr_flags, n_threads); -} - -template <class SVC_HANDLER> -ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (void) -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy"); -} - -template <class SVC_HANDLER> -ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy (void) -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy"); -} - -template <class SVC_HANDLER> int -ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg) -{ - ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler"); - switch (ACE_OS::fork ()) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), -1); - /* NOTREACHED */ - case 0: // In child process. - // 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. - return 0; - } -} - -template <class SVC_HANDLER> -ACE_Scheduling_Strategy<SVC_HANDLER>::ACE_Scheduling_Strategy (SVC_HANDLER *scheduler) - : scheduler_ (scheduler), - delete_scheduler_ (0) -{ - ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::ACE_Scheduling_Strategy"); - - if (this->scheduler_ == 0) - { - // Create a new SVC_HANDLER and assign the global Thread_Manager - // and Reactor to it... - ACE_NEW (this->scheduler_, SVC_HANDLER); - - if (this->scheduler_->thr_mgr () == 0) - this->scheduler_->thr_mgr (ACE_Service_Config::thr_mgr ()); - - if (this->scheduler_->reactor () == 0) - this->scheduler_->reactor (ACE_Service_Config::reactor ()); - - this->delete_scheduler_ = 1; - } -} - -template <class SVC_HANDLER> -ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy (void) -{ - ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy"); - - if (this->delete_scheduler_) - this->scheduler_->destroy (); -} - -template <class SVC_HANDLER> void -ACE_Scheduling_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "scheduler_ = %x", this->scheduler_)); - ACE_DEBUG ((LM_DEBUG, "\ndelete_scheduler_ = %d", this->delete_scheduler_)); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -template <class SVC_HANDLER> int -ACE_Scheduling_Strategy<SVC_HANDLER>::suspend (void) -{ - ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::suspend"); - return -1; -} - -template <class SVC_HANDLER> int -ACE_Scheduling_Strategy<SVC_HANDLER>::resume (void) -{ - ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::resume"); - return -1; -} - -template <class SVC_HANDLER> -ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::ACE_Schedule_All_Reactive_Strategy - (SVC_HANDLER *scheduler) - : ACE_Scheduling_Strategy<SVC_HANDLER> (scheduler) -{ - ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::ACE_Schedule_All_Reactive_Strategy"); -} - -template <class SVC_HANDLER> int -ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend (void) -{ - ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend"); - return this->scheduler_->reactor ()->suspend_handlers (); -} - -template <class SVC_HANDLER> void -ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump"); - - ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); -} - -template <class SVC_HANDLER> int -ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume (void) -{ - ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume"); - return this->scheduler_->reactor ()->resume_handlers (); -} - -template <class SVC_HANDLER> -ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::ACE_Schedule_All_Threaded_Strategy - (SVC_HANDLER *scheduler) - : ACE_Scheduling_Strategy<SVC_HANDLER> (scheduler) -{ - ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::ACE_Schedule_All_Threaded_Strategy"); -} - -template <class SVC_HANDLER> int -ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend (void) -{ - ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend"); - return this->scheduler_->thr_mgr ()->suspend_all (); -} - -template <class SVC_HANDLER> int -ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void) -{ - ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume"); - return this->scheduler_->thr_mgr ()->resume_all (); -} - -template <class SVC_HANDLER> void -ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump (void) const -{ - ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump"); - - ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); + return this->reactorex_->notify (eh, mask); } #endif /* ACE_STRATEGIES_C */ diff --git a/ace/Strategies.h b/ace/Strategies.h index 02129cca648..59dbb2d31ec 100644 --- a/ace/Strategies.h +++ b/ace/Strategies.h @@ -17,417 +17,50 @@ #if !defined (ACE_STRATEGIES_H) #define ACE_STRATEGIES_H -#include "ace/Service_Config.h" +#include "ace/Event_Handler.h" -template <class SVC_HANDLER> -class ACE_Creation_Strategy - // = TITLE - // Defines the interface for specifying a creation strategy for - // a SVC_HANDLER. - // - // = DESCRIPTION - // The default behavior is to make a new SVC_HANDLER. However, - // subclasses can override this strategy to perform SVC_HANDLER - // creation in any way that they like (such as creating subclass - // instances of SVC_HANDLER, using a singleton, dynamically - // linking the handler, etc.). -{ -public: - // = Initialization and termination methods. - - ACE_Creation_Strategy (ACE_Thread_Manager * = 0); - // Default constructor. - - int open (ACE_Thread_Manager * = 0); - // A <Thread_Manager> is useful when creating active objects. - - virtual ~ACE_Creation_Strategy (void); - - // = Factory method. - virtual SVC_HANDLER *make_svc_handler (void); - // Create a SVC_HANDLER with the appropriate creation strategy. The - // default behavior of this method is to make a new SVC_HANDLER, - // passing in the Thread_Manager (if any). - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - ACE_Thread_Manager *thr_mgr_; -}; - -template <class SVC_HANDLER> -class ACE_Singleton_Strategy : public ACE_Creation_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying a creation strategy for - // a <SVC_HANDLER> that always returns the same <SVC_HANDLER> (i.e., - // it's a Singleton). - // - // = DESCRIPTION - // Note that this class takes over the ownership of the - // SVC_HANDLER passed into it as a parameter and it becomes - // responsible for deleting this object. -{ -public: - // = Initialization and termination methods. - ACE_Singleton_Strategy (SVC_HANDLER * = 0, - ACE_Thread_Manager * = 0); - int open (SVC_HANDLER *, - ACE_Thread_Manager * = 0); - virtual ~ACE_Singleton_Strategy (void); - - // = Factory method. - virtual SVC_HANDLER *make_svc_handler (void); - // Create a Singleton SVC_HANDLER by always returning the same - // SVC_HANDLER. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - SVC_HANDLER *svc_handler_; - // Pointer to the Singleton svc_handler. -}; - -template <class SVC_HANDLER> -class ACE_DLL_Strategy : public ACE_Creation_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying a creation strategy for - // a SVC_HANDLER based on dynamic linking of the SVC_HANDLER. -{ -public: - // = Intialization and termination methods. - - ACE_DLL_Strategy (void); - // "Do-nothing" constructor. - - ACE_DLL_Strategy (const char svc_dll_info[], - ACE_Service_Config *, - ACE_Thread_Manager * = 0); - // Initialize the DLL strategy based upon the service's DLL - // information contained in the <svc_dll_info> string. - - int open (const char svc_dll_info[], - ACE_Service_Config *, - ACE_Thread_Manager * = 0); - // Initialize the DLL strategy based upon the service's DLL - // information contained in the <svc_dll_info> string. - - // = Factory method. - virtual SVC_HANDLER *make_svc_handler (void); - // Create a SVC_HANDLER by dynamically linking it from a DLL. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - typedef ACE_Creation_Strategy<SVC_HANDLER> inherited; - - char shared_library_[MAXPATHLEN]; - // Name of the shared library to dynamically link. - - char factory_function_[MAXPATHLEN]; - // Name of the factory function in the shared library to use to - // obtain a pointer to the new SVC_HANDLER. - - char svc_name[MAXNAMELEN]; - // Name of the service. - - ACE_Service_Config *svc_config_; - // Pointer to the Service_Configurator. -}; - -template <class SVC_HANDLER> -class ACE_Concurrency_Strategy - // = TITLE - // Defines the interface for specifying a concurrency strategy - // for a SVC_HANDLER. - // - // = DESCRIPTION - // Default behavior is to activate the SVC_HANDLER by calling - // its open() method (which allows the SVC_HANDLER to define its - // own concurrency strategy). However, subclasses can override - // this default strategy to do more sophisticated concurrency - // activations (such as creating the SVC_HANDLER as an active - // object via multi-threading or multi-processing). -{ -public: - // = Factory method. - virtual int activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg = 0); - // Activate the <svc_handler> with an appropriate concurrency - // strategy. The default behavior of this method is to activate the - // SVC_HANDLER by calling its open() method (which allows the - // SVC_HANDLER to define its own concurrency strategy). - - virtual ~ACE_Concurrency_Strategy (void); - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -template <class SVC_HANDLER> -class ACE_Thread_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying a concurrency strategy - // for a <SVC_HANDLER> based on multithreading. - // - // = DESCRIPTION - // This class provides a strategy that manages the creation of - // threads to handle requests from clients concurrently. It - // behaves as a "thread factory", spawning threads "on-demand" - // to run the service specified by a user-supplied - // <SVC_HANDLER>. -{ -public: - // = Intialization and termination methods. - ACE_Thread_Strategy (void); - // "Do-nothing constructor" - - ACE_Thread_Strategy (ACE_Thread_Manager *tm, - long thr_flags, - int n_threads = 1); - // Initialize the strategy. - - virtual int open (ACE_Thread_Manager *tm, - long thr_flags, - int n_threads = 1); - // Initialize the strategy. - - virtual ~ACE_Thread_Strategy (void); +// Forward decls. +class ACE_Reactor; +class ACE_ReactorEx; - // = Factory method. - virtual int activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg = 0); - // Activate the <svc_handler> with an appropriate concurrency - // strategy. This method activates the SVC_HANDLER by first calling - // its open() method and then calling its activate() method to turn - // it into an active object. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; - - ACE_Thread_Manager *thr_mgr_; - // Thread manager for this class (must be provided). - - long thr_flags_; - // Flags to pass into the SVC_HANDLER::activate() method. - - int n_threads_; - // Number of threads to spawn. -}; - -template <class SVC_HANDLER> -class ACE_Process_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying a concurrency strategy - // for a <SVC_HANDLER> based on multiprocessing. - // - // = DESCRIPTION - // This class provides a strategy that manages the creation of - // processes to handle requests from clients concurrently. It - // behaves as a "process factory", forking threads "on-demand" - // to run the service specified by a user-supplied - // <SVC_HANDLER>. -{ -public: - // = Intialization and termination methods. - ACE_Process_Strategy (void); - // "Do-nothing constructor" - - ACE_Process_Strategy (int n_processes = 1); - // Initialize the strategy. - - virtual int open (int n_processes = 1); - // Initialize the strategy. - - virtual ~ACE_Process_Strategy (void); - - // = Factory method. - virtual int activate_svc_handler (SVC_HANDLER *svc_handler, - void *arg = 0); - // Activate the <svc_handler> with an appropriate concurrency - // strategy. This method activates the SVC_HANDLER by first forking - // and then calling the open() method of the SVC_HANDLER in the - // child. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; - - int n_processes_; - // Number of processes to spawn. -}; - -template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> -class ACE_Accept_Strategy - // = TITLE - // Defines the interface for specifying a passive connection - // acceptance strategy for a SVC_HANDLER. - // - // = DESCRIPTION - // This class provides a strategy that manages passive - // connection acceptance of a client. +class ACE_Export ACE_Notification_Strategy { public: - // = Initialization and termination methods. - ACE_Accept_Strategy (void); - // Default constructor. - - ACE_Accept_Strategy (const ACE_PEER_ACCEPTOR_ADDR &local_addr, - int restart = 0); - // Initialize the <peer_acceptor_> with <local_addr>. - - virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, - int restart = 0); - // Initialize the <peer_acceptor_> with <local_addr>. - - virtual ACE_HANDLE get_handle (void) const; - // Return the underlying ACE_HANDLE of the <peer_acceptor_>. - - virtual ACE_PEER_ACCEPTOR &acceptor (void) const; - // Return a reference to the <peer_acceptor_>. - - virtual ~ACE_Accept_Strategy (void); - - // = Factory method. - virtual int accept_svc_handler (SVC_HANDLER *); - // The default behavior delegates to the <accept> method of the - // PEER_ACCEPTOR. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - ACE_PEER_ACCEPTOR peer_acceptor_; - // Factory that establishes connections passively. + virtual int notify (void) = 0; }; -template <class SVC_HANDLER> -class ACE_Scheduling_Strategy - // = TITLE - // Defines the interface for specifying how to suspend and - // resume a service . - // - // = DESCRIPTION - // This class provides a strategy that allows arbitrarily - // sophisticated service suspension and resumption. The default - // behavior is to do nothing... -{ -public: - // = Initialization and termination methods. - - ACE_Scheduling_Strategy (SVC_HANDLER * = 0); - // Constructor - - virtual ~ACE_Scheduling_Strategy (void); - // Destructor - - // = Scheduling methods +class ACE_Export ACE_Reactor_Notification_Strategy : public ACE_Notification_Strategy - virtual int suspend (void); - // Suspend hook. - - virtual int resume (void); - // Resume hook. - - virtual void dump (void) const; - // Dump the state of the object. - -protected: - SVC_HANDLER *scheduler_; - // Points to the scheduler strategy object... - - int delete_scheduler_; - // Keeps track of whether we need to delete this or not... -}; - -template <class SVC_HANDLER> -class ACE_Schedule_All_Reactive_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying how to suspend and - // resume a single-threaded reactive service . - // - // = DESCRIPTION - // This class provides a strategy that suspends and resumes all - // the Event_Handlers in a Reactor in one fell swoop. { public: - // = Initialization and termination methods. - ACE_Schedule_All_Reactive_Strategy (SVC_HANDLER * = 0); - // Constructor + ACE_Reactor_Notification_Strategy (ACE_Reactor *reactor, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); - // = Scheduling methods + virtual int notify (void); - virtual int suspend (void); - // Suspend hook. - - virtual int resume (void); - // Resume hook. - - virtual void dump (void) const; - // Dump the state of the object. +private: + ACE_Reactor *reactor_; + ACE_Event_Handler *eh_; + ACE_Reactor_Mask mask_; }; -template <class SVC_HANDLER> -class ACE_Schedule_All_Threaded_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER> - // = TITLE - // Defines the interface for specifying how to suspend and - // resume a multithreaded service . - // - // = DESCRIPTION - // This class provides a strategy that suspends and resumes all - // the Event_Handlers controlled by a Thread_Manager in one fell swoop. +class ACE_Export ACE_ReactorEx_Notification_Strategy : public ACE_Notification_Strategy { public: - // = Initialization and termination methods. - ACE_Schedule_All_Threaded_Strategy (SVC_HANDLER * = 0); - // Constructor - - // = Scheduling methods + ACE_ReactorEx_Notification_Strategy (ACE_ReactorEx *reactorex, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); - virtual int suspend (void); - // Suspend hook. + virtual int notify (void); - virtual int resume (void); - // Resume hook. - - virtual void dump (void) const; - // Dump the state of the object. +private: + ACE_ReactorEx *reactorex_; + ACE_Event_Handler *eh_; + ACE_Reactor_Mask mask_; }; -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "ace/Strategies.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("Strategies.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ +// This needs to come here to avoid circular dependencies. +#include "ace/Strategies_T.h" #endif /* ACE_STRATEGIES_H */ diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp new file mode 100644 index 00000000000..85ea21ee970 --- /dev/null +++ b/ace/Strategies_T.cpp @@ -0,0 +1,498 @@ +// Strategies_T.cpp +// $Id$ + +#if !defined (ACE_STRATEGIES_T_C) +#define ACE_STRATEGIES_T_C + +#define ACE_BUILD_DLL +#include "ace/Strategies_T.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Singleton_Strategy) + +template <class SVC_HANDLER> void +ACE_Singleton_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_Singleton_Strategy<SVC_HANDLER>::open (SVC_HANDLER *sh, + ACE_Thread_Manager *) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::open"); + if (this->svc_handler_ != 0) + delete this->svc_handler_; + + this->svc_handler_ = sh; + return 0; +} + +template <class SVC_HANDLER> +ACE_Singleton_Strategy<SVC_HANDLER>::ACE_Singleton_Strategy (SVC_HANDLER *sh, + ACE_Thread_Manager *tm) + : svc_handler_ (0) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::ACE_Singleton_Strategy"); + this->open (sh, tm); +} + +template <class SVC_HANDLER> +ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::~ACE_Singleton_Strategy"); + delete this->svc_handler_; +} + +// Create a Singleton SVC_HANDLER by always returning the same +// SVC_HANDLER. + +template <class SVC_HANDLER> SVC_HANDLER * +ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy<SVC_HANDLER>::make_svc_handler"); + return this->svc_handler_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy) + +template <class SVC_HANDLER> void +ACE_Creation_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_Creation_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::open"); + this->thr_mgr_ = thr_mgr; + return 0; +} + + +template <class SVC_HANDLER> +ACE_Creation_Strategy<SVC_HANDLER>::ACE_Creation_Strategy (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::ACE_Creation_Strategy"); + this->open (thr_mgr); +} + +// Default behavior is to make a new SVC_HANDLER, passing in the +// Thread_Manager (if any). + +template <class SVC_HANDLER> SVC_HANDLER * +ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::make_svc_handler"); + return new SVC_HANDLER (this->thr_mgr_); +} + +template <class SVC_HANDLER> +ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy (void) +{ + ACE_TRACE ("ACE_Creation_Strategy<SVC_HANDLER>::~ACE_Creation_Strategy"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy) + +template <class SVC_HANDLER> void +ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_DLL_Strategy<SVC_HANDLER>::open (const char svc_dll_info[], + ACE_Service_Config *svc_config, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::open"); + this->inherited::open (thr_mgr); + this->svc_config_ = svc_config; + return 0; +} + +template <class SVC_HANDLER> +ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy (const char svc_dll_info[], + ACE_Service_Config *sc, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy"); + if (this->open (svc_dll_info, sc, thr_mgr) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); +} + +template <class SVC_HANDLER> +ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy (void) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::ACE_DLL_Strategy"); +} + +// Create a SVC_HANDLER by dynamically linking it from a DLL. + +template <class SVC_HANDLER> SVC_HANDLER * +ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler (void) +{ + ACE_TRACE ("ACE_DLL_Strategy<SVC_HANDLER>::make_svc_handler"); + // Open the shared library. + void *handle = (void *) ACE_OS::dlopen (this->shared_library_); + + // Extract the factory function. + SVC_HANDLER *(*factory)(void) = (SVC_HANDLER *(*)(void)) ACE_OS::dlsym (handle, + this->factory_function_); + + // Call the factory function to obtain the new SVC_Handler (should + // use RTTI here when it becomes available...) + SVC_HANDLER *svc_handler = (*factory)(); + + if (svc_handler != 0) + { + // Create an ACE_Service_Record containing the SVC_Handler and + // insert into this->svc_config_->svc_rep; + + // @@ This remains to be implemented... + // @@ Somehow, we need to deal with this->thr_mgr_... + } + + return svc_handler; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Concurrency_Strategy) + +template <class SVC_HANDLER> void +ACE_Concurrency_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::dump"); +} + +// Default behavior is to activate the SVC_HANDLER by calling it's +// open() method, which allows the SVC_HANDLER to determine its own +// concurrency strategy. + +template <class SVC_HANDLER> int +ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::activate_svc_handler"); + // Delegate control to the application-specific service + // handler. + + if (svc_handler->open (arg) == -1) + { + // Close down handler to avoid resource leaks. + svc_handler->close (0); + return -1; + } + else + return 0; +} + +template <class SVC_HANDLER> +ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy (void) +{ + ACE_TRACE ("ACE_Concurrency_Strategy<SVC_HANDLER>::~ACE_Concurrency_Strategy"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) + +template <class SVC_HANDLER> void +ACE_Thread_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_Thread_Strategy<SVC_HANDLER>::open (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::open"); + this->thr_mgr_ = thr_mgr; + this->n_threads_ = n_threads; + this->thr_flags_ = thr_flags; + + // Must have a thread manager! + if (this->thr_mgr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "error: must have a non-NULL thread manager\n"), -1); + else + return 0; +} + +template <class SVC_HANDLER> +ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy"); + this->open (thr_mgr, thr_flags, n_threads); +} + +template <class SVC_HANDLER> +ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy (void) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::ACE_Thread_Strategy"); +} + +template <class SVC_HANDLER> +ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy (void) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::~ACE_Thread_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Thread_Strategy<SVC_HANDLER>::activate_svc_handler"); + // Call up to our parent to do the SVC_HANDLER initialization. + if (this->inherited::activate_svc_handler (svc_handler, arg) == -1) + return -1; + else + // Turn the <svc_handler> into an active object (if it isn't + // already one as a result of the first activation...) + return svc_handler->activate (this->thr_flags_, this->n_threads_); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Accept_Strategy) + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int restart) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy"); + + if (this->open (local_addr, restart) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open + (const ACE_PEER_ACCEPTOR_ADDR &local_addr, int restart) +{ + return this->peer_acceptor_.open (local_addr, restart); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump"); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy (void) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Accept_Strategy"); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler + (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler"); + + if (this->peer_acceptor_.accept (svc_handler->peer ()) == -1) + { + svc_handler->close (0); + return -1; + } + else + return 0; +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR & +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy (void) +{ + ACE_TRACE ("ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Accept_Strategy"); + if (this->peer_acceptor_.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy) + +template <class SVC_HANDLER> void +ACE_Process_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::dump"); +} + +template <class SVC_HANDLER> int +ACE_Process_Strategy<SVC_HANDLER>::open (int n_processes) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::open"); + this->n_processes_ = n_processes; + + return 0; +} + +template <class SVC_HANDLER> +ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (int n_processes) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy"); + this->open (thr_mgr, thr_flags, n_threads); +} + +template <class SVC_HANDLER> +ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy (void) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::ACE_Process_Strategy"); +} + +template <class SVC_HANDLER> +ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy (void) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::~ACE_Process_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Process_Strategy<SVC_HANDLER>::activate_svc_handler"); + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), -1); + /* NOTREACHED */ + case 0: // In child process. + // 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. + return 0; + } +} + +template <class SVC_HANDLER> +ACE_Scheduling_Strategy<SVC_HANDLER>::ACE_Scheduling_Strategy (SVC_HANDLER *scheduler) + : scheduler_ (scheduler), + delete_scheduler_ (0) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::ACE_Scheduling_Strategy"); + + if (this->scheduler_ == 0) + { + // Create a new SVC_HANDLER and assign the global Thread_Manager + // and Reactor to it... + ACE_NEW (this->scheduler_, SVC_HANDLER); + + if (this->scheduler_->thr_mgr () == 0) + this->scheduler_->thr_mgr (ACE_Service_Config::thr_mgr ()); + + if (this->scheduler_->reactor () == 0) + this->scheduler_->reactor (ACE_Service_Config::reactor ()); + + this->delete_scheduler_ = 1; + } +} + +template <class SVC_HANDLER> +ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::~ACE_Scheduling_Strategy"); + + if (this->delete_scheduler_) + this->scheduler_->destroy (); +} + +template <class SVC_HANDLER> void +ACE_Scheduling_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "scheduler_ = %x", this->scheduler_)); + ACE_DEBUG ((LM_DEBUG, "\ndelete_scheduler_ = %d", this->delete_scheduler_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template <class SVC_HANDLER> int +ACE_Scheduling_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::suspend"); + return -1; +} + +template <class SVC_HANDLER> int +ACE_Scheduling_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy<SVC_HANDLER>::resume"); + return -1; +} + +template <class SVC_HANDLER> +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::ACE_Schedule_All_Reactive_Strategy + (SVC_HANDLER *scheduler) + : ACE_Scheduling_Strategy<SVC_HANDLER> (scheduler) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::ACE_Schedule_All_Reactive_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::suspend"); + return this->scheduler_->reactor ()->suspend_handlers (); +} + +template <class SVC_HANDLER> void +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::dump"); + + ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SVC_HANDLER>::resume"); + return this->scheduler_->reactor ()->resume_handlers (); +} + +template <class SVC_HANDLER> +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::ACE_Schedule_All_Threaded_Strategy + (SVC_HANDLER *scheduler) + : ACE_Scheduling_Strategy<SVC_HANDLER> (scheduler) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::ACE_Schedule_All_Threaded_Strategy"); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::suspend"); + return this->scheduler_->thr_mgr ()->suspend_all (); +} + +template <class SVC_HANDLER> int +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume"); + return this->scheduler_->thr_mgr ()->resume_all (); +} + +template <class SVC_HANDLER> void +ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump (void) const +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump"); + + ACE_Scheduling_Strategy<SVC_HANDLER>::dump (); +} + +#endif /* ACE_STRATEGIES_T_C */ diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h new file mode 100644 index 00000000000..3834a980eda --- /dev/null +++ b/ace/Strategies_T.h @@ -0,0 +1,433 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Strategies_T.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_STRATEGIES_T_H) +#define ACE_STRATEGIES_T_H + +#include "ace/Service_Config.h" + +template <class SVC_HANDLER> +class ACE_Creation_Strategy + // = TITLE + // Defines the interface for specifying a creation strategy for + // a SVC_HANDLER. + // + // = DESCRIPTION + // The default behavior is to make a new SVC_HANDLER. However, + // subclasses can override this strategy to perform SVC_HANDLER + // creation in any way that they like (such as creating subclass + // instances of SVC_HANDLER, using a singleton, dynamically + // linking the handler, etc.). +{ +public: + // = Initialization and termination methods. + + ACE_Creation_Strategy (ACE_Thread_Manager * = 0); + // Default constructor. + + int open (ACE_Thread_Manager * = 0); + // A <Thread_Manager> is useful when creating active objects. + + virtual ~ACE_Creation_Strategy (void); + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a SVC_HANDLER with the appropriate creation strategy. The + // default behavior of this method is to make a new SVC_HANDLER, + // passing in the Thread_Manager (if any). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Thread_Manager *thr_mgr_; +}; + +template <class SVC_HANDLER> +class ACE_Singleton_Strategy : public ACE_Creation_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying a creation strategy for + // a <SVC_HANDLER> that always returns the same <SVC_HANDLER> (i.e., + // it's a Singleton). + // + // = DESCRIPTION + // Note that this class takes over the ownership of the + // SVC_HANDLER passed into it as a parameter and it becomes + // responsible for deleting this object. +{ +public: + // = Initialization and termination methods. + ACE_Singleton_Strategy (SVC_HANDLER * = 0, + ACE_Thread_Manager * = 0); + int open (SVC_HANDLER *, + ACE_Thread_Manager * = 0); + virtual ~ACE_Singleton_Strategy (void); + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a Singleton SVC_HANDLER by always returning the same + // SVC_HANDLER. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + SVC_HANDLER *svc_handler_; + // Pointer to the Singleton svc_handler. +}; + +template <class SVC_HANDLER> +class ACE_DLL_Strategy : public ACE_Creation_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying a creation strategy for + // a SVC_HANDLER based on dynamic linking of the SVC_HANDLER. +{ +public: + // = Intialization and termination methods. + + ACE_DLL_Strategy (void); + // "Do-nothing" constructor. + + ACE_DLL_Strategy (const char svc_dll_info[], + ACE_Service_Config *, + ACE_Thread_Manager * = 0); + // Initialize the DLL strategy based upon the service's DLL + // information contained in the <svc_dll_info> string. + + int open (const char svc_dll_info[], + ACE_Service_Config *, + ACE_Thread_Manager * = 0); + // Initialize the DLL strategy based upon the service's DLL + // information contained in the <svc_dll_info> string. + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a SVC_HANDLER by dynamically linking it from a DLL. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Creation_Strategy<SVC_HANDLER> inherited; + + char shared_library_[MAXPATHLEN]; + // Name of the shared library to dynamically link. + + char factory_function_[MAXPATHLEN]; + // Name of the factory function in the shared library to use to + // obtain a pointer to the new SVC_HANDLER. + + char svc_name[MAXNAMELEN]; + // Name of the service. + + ACE_Service_Config *svc_config_; + // Pointer to the Service_Configurator. +}; + +template <class SVC_HANDLER> +class ACE_Concurrency_Strategy + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a SVC_HANDLER. + // + // = DESCRIPTION + // Default behavior is to activate the SVC_HANDLER by calling + // its open() method (which allows the SVC_HANDLER to define its + // own concurrency strategy). However, subclasses can override + // this default strategy to do more sophisticated concurrency + // activations (such as creating the SVC_HANDLER as an active + // object via multi-threading or multi-processing). +{ +public: + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the <svc_handler> with an appropriate concurrency + // strategy. The default behavior of this method is to activate the + // SVC_HANDLER by calling its open() method (which allows the + // SVC_HANDLER to define its own concurrency strategy). + + virtual ~ACE_Concurrency_Strategy (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template <class SVC_HANDLER> +class ACE_Thread_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a <SVC_HANDLER> based on multithreading. + // + // = DESCRIPTION + // This class provides a strategy that manages the creation of + // threads to handle requests from clients concurrently. It + // behaves as a "thread factory", spawning threads "on-demand" + // to run the service specified by a user-supplied + // <SVC_HANDLER>. +{ +public: + // = Intialization and termination methods. + ACE_Thread_Strategy (void); + // "Do-nothing constructor" + + ACE_Thread_Strategy (ACE_Thread_Manager *tm, + long thr_flags, + int n_threads = 1); + // Initialize the strategy. + + virtual int open (ACE_Thread_Manager *tm, + long thr_flags, + int n_threads = 1); + // Initialize the strategy. + + virtual ~ACE_Thread_Strategy (void); + + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the <svc_handler> with an appropriate concurrency + // strategy. This method activates the SVC_HANDLER by first calling + // its open() method and then calling its activate() method to turn + // it into an active object. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; + + ACE_Thread_Manager *thr_mgr_; + // Thread manager for this class (must be provided). + + long thr_flags_; + // Flags to pass into the SVC_HANDLER::activate() method. + + int n_threads_; + // Number of threads to spawn. +}; + +template <class SVC_HANDLER> +class ACE_Process_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a <SVC_HANDLER> based on multiprocessing. + // + // = DESCRIPTION + // This class provides a strategy that manages the creation of + // processes to handle requests from clients concurrently. It + // behaves as a "process factory", forking threads "on-demand" + // to run the service specified by a user-supplied + // <SVC_HANDLER>. +{ +public: + // = Intialization and termination methods. + ACE_Process_Strategy (void); + // "Do-nothing constructor" + + ACE_Process_Strategy (int n_processes = 1); + // Initialize the strategy. + + virtual int open (int n_processes = 1); + // Initialize the strategy. + + virtual ~ACE_Process_Strategy (void); + + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the <svc_handler> with an appropriate concurrency + // strategy. This method activates the SVC_HANDLER by first forking + // and then calling the open() method of the SVC_HANDLER in the + // child. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Concurrency_Strategy<SVC_HANDLER> inherited; + + int n_processes_; + // Number of processes to spawn. +}; + +template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> +class ACE_Accept_Strategy + // = TITLE + // Defines the interface for specifying a passive connection + // acceptance strategy for a SVC_HANDLER. + // + // = DESCRIPTION + // This class provides a strategy that manages passive + // connection acceptance of a client. +{ +public: + // = Initialization and termination methods. + ACE_Accept_Strategy (void); + // Default constructor. + + ACE_Accept_Strategy (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + int restart = 0); + // Initialize the <peer_acceptor_> with <local_addr>. + + virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + int restart = 0); + // Initialize the <peer_acceptor_> with <local_addr>. + + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying ACE_HANDLE of the <peer_acceptor_>. + + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + // Return a reference to the <peer_acceptor_>. + + virtual ~ACE_Accept_Strategy (void); + + // = Factory method. + virtual int accept_svc_handler (SVC_HANDLER *); + // The default behavior delegates to the <accept> method of the + // PEER_ACCEPTOR. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_PEER_ACCEPTOR peer_acceptor_; + // Factory that establishes connections passively. +}; + +template <class SVC_HANDLER> +class ACE_Scheduling_Strategy + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a service . + // + // = DESCRIPTION + // This class provides a strategy that allows arbitrarily + // sophisticated service suspension and resumption. The default + // behavior is to do nothing... +{ +public: + // = Initialization and termination methods. + + ACE_Scheduling_Strategy (SVC_HANDLER * = 0); + // Constructor + + virtual ~ACE_Scheduling_Strategy (void); + // Destructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. + +protected: + SVC_HANDLER *scheduler_; + // Points to the scheduler strategy object... + + int delete_scheduler_; + // Keeps track of whether we need to delete this or not... +}; + +template <class SVC_HANDLER> +class ACE_Schedule_All_Reactive_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a single-threaded reactive service . + // + // = DESCRIPTION + // This class provides a strategy that suspends and resumes all + // the Event_Handlers in a Reactor in one fell swoop. +{ +public: + // = Initialization and termination methods. + ACE_Schedule_All_Reactive_Strategy (SVC_HANDLER * = 0); + // Constructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. +}; + +template <class SVC_HANDLER> +class ACE_Schedule_All_Threaded_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER> + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a multithreaded service . + // + // = DESCRIPTION + // This class provides a strategy that suspends and resumes all + // the Event_Handlers controlled by a Thread_Manager in one fell swoop. +{ +public: + // = Initialization and termination methods. + ACE_Schedule_All_Threaded_Strategy (SVC_HANDLER * = 0); + // Constructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Strategies_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Strategies_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_STRATEGIES_T_H */ diff --git a/ace/Synch.h b/ace/Synch.h index a948b3fd285..2c19f277b4b 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -967,7 +967,7 @@ public: LPCTSTR = 0, void * = 0): mutex_ (m) {} ~ACE_Null_Condition_Mutex (void) {} int remove (void) { return 0; } - int wait (ACE_Time_Value * = 0) { return 0; } + int wait (ACE_Time_Value * = 0) { errno = ETIME; return -1; } int signal (void) { return 0; } int broadcast (void) { return 0; } ACE_Null_Mutex &mutex (void) { return this->mutex_; } diff --git a/ace/Task_T.h b/ace/Task_T.h index d3ede819283..9549a05b90b 100644 --- a/ace/Task_T.h +++ b/ace/Task_T.h @@ -93,8 +93,12 @@ public: // Should be protected: ACE_Module<ACE_SYNCH_2> *module (void) const; // Return the Task's Module if there is one, else returns 0. - int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); /* Flush the queue */ - // Special routines corresponding to certain message types. + int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); + // Flush the queue. Note that if this conflicts with the C++ + // iostream flush() function, just rewrite the iostream function as + // ::flush(). + + // = Special routines corresponding to certain message types. void water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds, size_t); // Manipulate watermarks. |