OSDN Git Service

* Makefile.in: Add -lntdll to link line.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygserver / process.h
1 /* process.h
2
3    Copyright 2001, 2002, 2003, 2004, 2005 Red Hat Inc.
4
5    Written by Robert Collins <rbtcollins@hotmail.com>
6
7 This file is part of Cygwin.
8
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
11 details. */
12
13 #ifndef _PROCESS_H
14 #define _PROCESS_H
15
16 #include <assert.h>
17
18 #include "threaded_queue.h"
19
20 class process_cleanup : public queue_request
21 {
22 public:
23   process_cleanup (class process *const theprocess)
24     : _process (theprocess)
25   {
26     assert (_process);
27   }
28
29   virtual ~process_cleanup ();
30
31   virtual void process ();
32
33 private:
34   class process *const _process;
35 };
36
37 class process;
38
39 class cleanup_routine
40 {
41   friend class process;
42
43 public:
44   cleanup_routine (void *const key)
45     : _key (key),
46       _next (NULL)
47   {}
48
49   virtual ~cleanup_routine () = 0;
50
51   bool operator== (const cleanup_routine &rhs) const
52   {
53     return _key == rhs._key;
54   }
55
56   void *key () const { return _key; }
57
58   /* MUST BE SYNCHRONOUS */
59   virtual void cleanup (class process *) = 0;
60
61 private:
62   void *const _key;
63   cleanup_routine *_next;
64 };
65
66 class process_cache;
67
68 #define hold()          _hold(__FILE__,__LINE__)
69 #define release()       _release(__FILE__,__LINE__)
70
71 class process
72 {
73   friend class process_cache;
74   friend class process_cleanup;
75
76 public:
77   process (pid_t cygpid, DWORD winpid,
78            HANDLE signal_arrived = INVALID_HANDLE_VALUE);
79   ~process ();
80
81   pid_t cygpid () const { return _cygpid; }
82   DWORD winpid () const { return _winpid; }
83   HANDLE handle () const { return _hProcess; }
84   HANDLE signal_arrived () const { return _signal_arrived; }
85
86   bool is_active () const { return _exit_status == STILL_ACTIVE; }
87
88   void _hold (const char *file, int line) {
89     _log (file, line, LOG_DEBUG, "Try hold(%lu)", _cygpid);
90     EnterCriticalSection (&_access);
91     _log (file, line, LOG_DEBUG, "holding (%lu)", _cygpid);
92   }
93   void _release (const char *file, int line) {
94     _log (file, line, LOG_DEBUG, "leaving (%lu)", _cygpid);
95     LeaveCriticalSection (&_access);
96   }
97
98   bool add (cleanup_routine *);
99   bool remove (const cleanup_routine *);
100
101 private:
102   const pid_t _cygpid;
103   const DWORD _winpid;
104   HANDLE _hProcess;
105   HANDLE _signal_arrived;
106   long _cleaning_up;
107   DWORD _exit_status;           // Set in the constructor and in exit_code ().
108   cleanup_routine *_routines_head;
109   /* used to prevent races-on-delete */
110   CRITICAL_SECTION _access;
111   class process *_next;
112
113   DWORD check_exit_code ();
114   void cleanup ();
115 };
116
117 class process_cache
118 {
119   // Number of special (i.e., non-process) handles in _wait_array.
120   // See wait_for_processes () and sync_wait_array () for details.
121   enum {
122     SPECIALS_COUNT = 2
123   };
124
125   class submission_loop : public queue_submission_loop
126   {
127   public:
128     submission_loop (process_cache *const cache, threaded_queue *const queue)
129       : queue_submission_loop (queue, true),
130         _cache (cache)
131     {
132       assert (_cache);
133     }
134
135   private:
136     process_cache *const _cache;
137
138     virtual void request_loop ();
139   };
140
141   friend class submission_loop;
142
143 public:
144   process_cache (const size_t max_procs, const unsigned int initial_workers);
145   ~process_cache ();
146
147   class process *process (pid_t cygpid, DWORD winpid,
148                           HANDLE signal_arrived = INVALID_HANDLE_VALUE);
149
150   bool running () const { return _queue.running (); }
151
152   bool start () { return _queue.start (); }
153   bool stop () { return _queue.stop (); }
154
155 private:
156   threaded_queue _queue;
157   submission_loop _submitter;
158
159   size_t _processes_count;
160   size_t _max_process_count;
161   class process *_processes_head; // A list sorted by winpid.
162
163   // Access to the _wait_array and related fields is not thread-safe,
164   // since they are used solely by wait_for_processes () and its callees.
165
166   HANDLE _wait_array[5 * MAXIMUM_WAIT_OBJECTS];
167   class process *_process_array[5 * MAXIMUM_WAIT_OBJECTS];
168
169   HANDLE _cache_add_trigger;    // Actually both add and remove.
170   CRITICAL_SECTION _cache_write_access; // Actually both read and write access.
171
172   void wait_for_processes (HANDLE interrupt);
173   size_t sync_wait_array (HANDLE interrupt);
174   void check_and_remove_process (const size_t index);
175
176   class process *find (DWORD winpid, class process **previous = NULL);
177 };
178
179 #endif /* _PROCESS_H */