3 Copyright 2001, 2002, 2003, 2004, 2005, 2012, 2015 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
);
80 pid_t
cygpid () const { return _cygpid
; }
81 DWORD
winpid () const { return _winpid
; }
82 HANDLE
handle () const { return _hProcess
; }
84 bool is_active () const { return _exit_status
== STILL_ACTIVE
; }
86 void _hold (const char *file
, int line
) {
87 _log (file
, line
, LOG_DEBUG
, "Try hold(%lu)", _cygpid
);
88 EnterCriticalSection (&_access
);
89 _log (file
, line
, LOG_DEBUG
, "holding (%lu)", _cygpid
);
91 void _release (const char *file
, int line
) {
92 _log (file
, line
, LOG_DEBUG
, "leaving (%lu)", _cygpid
);
93 LeaveCriticalSection (&_access
);
96 bool add (cleanup_routine
*);
97 bool remove (const cleanup_routine
*);
104 DWORD _exit_status
; // Set in the constructor and in exit_code ().
105 cleanup_routine
*_routines_head
;
106 /* used to prevent races-on-delete */
107 CRITICAL_SECTION _access
;
108 class process
*_next
;
110 DWORD
check_exit_code ();
116 // Number of special (i.e., non-process) handles in _wait_array.
117 // See wait_for_processes () and sync_wait_array () for details.
122 class submission_loop
: public queue_submission_loop
125 submission_loop (process_cache
*const cache
, threaded_queue
*const queue
)
126 : queue_submission_loop (queue
, true),
133 process_cache
*const _cache
;
135 virtual void request_loop ();
138 friend class submission_loop
;
141 process_cache (const size_t max_procs
, const unsigned int initial_workers
);
144 class process
*process (pid_t cygpid
, DWORD winpid
);
146 bool running () const { return _queue
.running (); }
148 bool start () { return _queue
.start (); }
149 bool stop () { return _queue
.stop (); }
152 threaded_queue _queue
;
153 submission_loop _submitter
;
155 size_t _processes_count
;
156 size_t _max_process_count
;
157 class process
*_processes_head
; // A list sorted by winpid.
159 // Access to the _wait_array and related fields is not thread-safe,
160 // since they are used solely by wait_for_processes () and its callees.
162 HANDLE _wait_array
[5 * MAXIMUM_WAIT_OBJECTS
];
163 class process
*_process_array
[5 * MAXIMUM_WAIT_OBJECTS
];
165 HANDLE _cache_add_trigger
; // Actually both add and remove.
166 CRITICAL_SECTION _cache_write_access
; // Actually both read and write access.
168 void wait_for_processes (HANDLE interrupt
);
169 size_t sync_wait_array (HANDLE interrupt
);
170 void check_and_remove_process (const size_t index
);
172 class process
*find (DWORD winpid
, class process
**previous
= NULL
);
175 #endif /* _PROCESS_H */