3 Written by Robert Collins <rbtcollins@hotmail.com>
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
16 #include "threaded_queue.h"
18 class process_cleanup
: public queue_request
21 process_cleanup (class process
*const theprocess
)
22 : _process (theprocess
)
27 virtual ~process_cleanup ();
29 virtual void process ();
32 class process
*const _process
;
42 cleanup_routine (void *const key
)
47 virtual ~cleanup_routine () = 0;
49 bool operator== (const cleanup_routine
&rhs
) const
51 return _key
== rhs
._key
;
54 void *key () const { return _key
; }
56 /* MUST BE SYNCHRONOUS */
57 virtual void cleanup (class process
*) = 0;
61 cleanup_routine
*_next
;
66 #define hold() _hold(__FILE__,__LINE__)
67 #define release() _release(__FILE__,__LINE__)
71 friend class process_cache
;
72 friend class process_cleanup
;
75 process (pid_t cygpid
, DWORD winpid
);
78 pid_t
cygpid () const { return _cygpid
; }
79 DWORD
winpid () const { return _winpid
; }
80 HANDLE
handle () const { return _hProcess
; }
82 bool is_active () const { return _exit_status
== STILL_ACTIVE
; }
84 void _hold (const char *file
, int line
) {
85 _debug (file
, line
, "Try hold(%lu)", _cygpid
);
86 EnterCriticalSection (&_access
);
87 _debug (file
, line
, "holding (%lu)", _cygpid
);
89 void _release (const char *file
, int line
) {
90 _debug (file
, line
, "leaving (%lu)", _cygpid
);
91 LeaveCriticalSection (&_access
);
94 bool add (cleanup_routine
*);
95 bool remove (const cleanup_routine
*);
102 DWORD _exit_status
; // Set in the constructor and in exit_code ().
103 cleanup_routine
*_routines_head
;
104 /* used to prevent races-on-delete */
105 CRITICAL_SECTION _access
;
106 class process
*_next
;
108 DWORD
check_exit_code ();
114 // Number of special (i.e., non-process) handles in _wait_array.
115 // See wait_for_processes () and sync_wait_array () for details.
120 class submission_loop
: public queue_submission_loop
123 submission_loop (process_cache
*const cache
, threaded_queue
*const queue
)
124 : queue_submission_loop (queue
, true),
131 process_cache
*const _cache
;
133 virtual void request_loop ();
136 friend class submission_loop
;
139 process_cache (const size_t max_procs
, const unsigned int initial_workers
);
142 class process
*process (pid_t cygpid
, DWORD winpid
);
144 bool running () const { return _queue
.running (); }
146 bool start () { return _queue
.start (); }
147 bool stop () { return _queue
.stop (); }
150 threaded_queue _queue
;
151 submission_loop _submitter
;
153 size_t _processes_count
;
154 size_t _max_process_count
;
155 class process
*_processes_head
; // A list sorted by winpid.
157 // Access to the _wait_array and related fields is not thread-safe,
158 // since they are used solely by wait_for_processes () and its callees.
160 HANDLE _wait_array
[5 * MAXIMUM_WAIT_OBJECTS
];
161 class process
*_process_array
[5 * MAXIMUM_WAIT_OBJECTS
];
163 HANDLE _cache_add_trigger
; // Actually both add and remove.
164 CRITICAL_SECTION _cache_write_access
; // Actually both read and write access.
166 void wait_for_processes (HANDLE interrupt
);
167 size_t sync_wait_array (HANDLE interrupt
);
168 void check_and_remove_process (const size_t index
);
170 class process
*find (DWORD winpid
, class process
**previous
= NULL
);
173 #endif /* _PROCESS_H */