diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog index fcc3b28a5..c30805639 100644 --- a/winsup/cygserver/ChangeLog +++ b/winsup/cygserver/ChangeLog @@ -1,3 +1,7 @@ +2003-08-30 Christopher Faylor + + * threaded_queue.h: New file. + 2003-08-25 Christopher Faylor * Makefile.in: Build libcygserver.a. diff --git a/winsup/cygserver/threaded_queue.h b/winsup/cygserver/threaded_queue.h new file mode 100644 index 000000000..5b6fddc42 --- /dev/null +++ b/winsup/cygserver/threaded_queue.h @@ -0,0 +1,127 @@ +/* threaded_queue.h + + Copyright 2001, 2002 Red Hat Inc. + + Written by Robert Collins + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _THREADED_QUEUE_ +#define _THREADED_QUEUE_ + +/*****************************************************************************/ + +/* a specific request */ + +class queue_request +{ +public: + queue_request *_next; + + queue_request () : _next (NULL) {} + virtual ~queue_request (); + + virtual void process () = 0; +}; + +/*****************************************************************************/ + +/* a queue to allocate requests from n submission loops to x worker threads */ + +class queue_submission_loop; + +class threaded_queue +{ +public: + threaded_queue (size_t initial_workers = 1); + ~threaded_queue (); + + void add_submission_loop (queue_submission_loop *); + + bool running () const { return _running; } + + bool start (); + bool stop (); + + void add (queue_request *); + +private: + long _workers_count; + bool _running; + + queue_submission_loop *_submitters_head; + + long _requests_count; // Informational only. + queue_request *_requests_head; + + CRITICAL_SECTION _queue_lock; + HANDLE _requests_sem; // == _requests_count + + static DWORD WINAPI start_routine (LPVOID /* this */); + + void create_workers (size_t initial_workers); + void worker_loop (); +}; + +/*****************************************************************************/ + +/* parameters for a request finding and submitting loop */ + +class queue_submission_loop +{ + friend class threaded_queue; + +public: + queue_submission_loop (threaded_queue *, bool ninterruptible); + virtual ~queue_submission_loop (); + + bool start (); + bool stop (); + + threaded_queue *queue () { return _queue; }; + +protected: + bool _running; + HANDLE _interrupt_event; + threaded_queue *const _queue; + +private: + bool _interruptible; + HANDLE _hThread; + DWORD _tid; + queue_submission_loop *_next; + + static DWORD WINAPI start_routine (LPVOID /* this */); + virtual void request_loop () = 0; +}; + +#ifdef __cplusplus + +/*---------------------------------------------------------------------------* + * Some type-safe versions of the various interlocked functions. + *---------------------------------------------------------------------------*/ + +template T * +TInterlockedExchangePointer (T **lvalue, T *rvalue) +{ + return reinterpret_cast + (InterlockedExchangePointer (reinterpret_cast (lvalue), + reinterpret_cast (rvalue))); +} + +template T * +TInterlockedCompareExchangePointer (T **lvalue, T *rvalue1, T *rvalue2) +{ + return reinterpret_cast + (InterlockedCompareExchangePointer (reinterpret_cast (lvalue), + reinterpret_cast (rvalue1), + reinterpret_cast (rvalue2))); +} + +#endif /* __cplusplus */ + +#endif /* _THREADED_QUEUE_ */