3 Copyright 2001, 2002, 2003, 2004, 2005, 2012 Red Hat Inc.
5 Written by Robert Collins <rbtcollins@hotmail.com>
7 This file is part of Cygwin.
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
18 #include "threaded_queue.h"
20 class process_cleanup
: public queue_request
23 process_cleanup (class process
*const theprocess
)
24 : _process (theprocess
)
29 virtual ~process_cleanup ();
31 virtual void process ();
34 class process
*const _process
;
44 cleanup_routine (void *const key
)
49 virtual ~cleanup_routine () = 0;
51 bool operator== (const cleanup_routine
&rhs
) const
53 return _key
== rhs
._key
;
56 void *key () const { return _key
; }
58 /* MUST BE SYNCHRONOUS */
59 virtual void cleanup (class process
*) = 0;
63 cleanup_routine
*_next
;
68 #define hold() _hold(__FILE__,__LINE__)
69 #define release() _release(__FILE__,__LINE__)
73 friend class process_cache
;
74 friend class process_cleanup
;
77 process (pid_t cygpid
, DWORD winpid
,
78 HANDLE signal_arrived
= INVALID_HANDLE_VALUE
);
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
; }
86 bool is_active () const { return _exit_status
== STILL_ACTIVE
; }
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
);
93 void _release (const char *file
, int line
) {
94 _log (file
, line
, LOG_DEBUG
, "leaving (%lu)", _cygpid
);
95 LeaveCriticalSection (&_access
);
98 bool add (cleanup_routine
*);
99 bool remove (const cleanup_routine
*);
105 HANDLE _signal_arrived
;
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
;
113 DWORD
check_exit_code ();
119 // Number of special (i.e., non-process) handles in _wait_array.
120 // See wait_for_processes () and sync_wait_array () for details.
125 class submission_loop
: public queue_submission_loop
128 submission_loop (process_cache
*const cache
, threaded_queue
*const queue
)
129 : queue_submission_loop (queue
, true),
136 process_cache
*const _cache
;
138 virtual void request_loop ();
141 friend class submission_loop
;
144 process_cache (const size_t max_procs
, const unsigned int initial_workers
);
147 class process
*process (pid_t cygpid
, DWORD winpid
,
148 HANDLE signal_arrived
= INVALID_HANDLE_VALUE
);
150 bool running () const { return _queue
.running (); }
152 bool start () { return _queue
.start (); }
153 bool stop () { return _queue
.stop (); }
156 threaded_queue _queue
;
157 submission_loop _submitter
;
159 size_t _processes_count
;
160 size_t _max_process_count
;
161 class process
*_processes_head
; // A list sorted by winpid.
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.
166 HANDLE _wait_array
[5 * MAXIMUM_WAIT_OBJECTS
];
167 class process
*_process_array
[5 * MAXIMUM_WAIT_OBJECTS
];
169 HANDLE _cache_add_trigger
; // Actually both add and remove.
170 CRITICAL_SECTION _cache_write_access
; // Actually both read and write access.
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
);
176 class process
*find (DWORD winpid
, class process
**previous
= NULL
);
179 #endif /* _PROCESS_H */