summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-05-16 10:46:35 -0400
committerAndreas Schneider <asn@samba.org>2011-08-10 18:14:04 +0200
commit0a910c93472e1e4aff120219e09866d4a20ec2b2 (patch)
tree21b595373c4fe52393fbafafe3376959799c8ff2
parente0aa6eec0b498db345666df4b02d4917fa3e259a (diff)
downloadsamba-0a910c93472e1e4aff120219e09866d4a20ec2b2.tar.gz
samba-0a910c93472e1e4aff120219e09866d4a20ec2b2.tar.bz2
samba-0a910c93472e1e4aff120219e09866d4a20ec2b2.zip
s3-prefork: Provide a cleanup function
This way the parent doesn't need to know how to handle dead children and keeps all of that within the prefork abstraction. Signed-off-by: Andreas Schneider <asn@samba.org>
-rw-r--r--source3/lib/server_prefork.c26
-rw-r--r--source3/lib/server_prefork.h12
-rw-r--r--source3/printing/spoolssd.c15
3 files changed, 25 insertions, 28 deletions
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c
index 211a54b95b..ef76a55486 100644
--- a/source3/lib/server_prefork.c
+++ b/source3/lib/server_prefork.c
@@ -291,29 +291,37 @@ int prefork_count_active_children(struct prefork_pool *pfp, int *total)
return a;
}
-/* to be used to finally mark a children as dead, so that it's slot can
- * be reused */
-bool prefork_mark_pid_dead(struct prefork_pool *pfp, pid_t pid)
+void prefork_cleanup_loop(struct prefork_pool *pfp)
{
+ int status;
+ pid_t pid;
int i;
+ /* TODO: should we use a process group id wait instead of looping ? */
for (i = 0; i < pfp->pool_size; i++) {
- if (pfp->pool[i].pid == pid) {
+ if (pfp->pool[i].status == PF_WORKER_NONE ||
+ pfp->pool[i].pid == 0) {
+ continue;
+ }
+
+ pid = sys_waitpid(pfp->pool[i].pid, &status, WNOHANG);
+ if (pid > 0) {
+
if (pfp->pool[i].status != PF_WORKER_EXITING) {
- DEBUG(2, ("pid %d terminated abnormally!\n",
- (int)pid));
+ DEBUG(3, ("Child (%d) terminated abnormally:"
+ " %d\n", (int)pid, status));
+ } else {
+ DEBUG(10, ("Child (%d) terminated with status:"
+ " %d\n", (int)pid, status));
}
/* reset all fields,
* this makes status = PF_WORK_NONE */
memset(&pfp->pool[i], 0,
sizeof(struct pf_worker_data));
-
- return true;
}
}
- return false;
}
void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max)
diff --git a/source3/lib/server_prefork.h b/source3/lib/server_prefork.h
index f5c86b4043..f4d03ccca1 100644
--- a/source3/lib/server_prefork.h
+++ b/source3/lib/server_prefork.h
@@ -160,18 +160,14 @@ int prefork_retire_children(struct prefork_pool *pfp,
* @return The number of children actually serving clients
*/
int prefork_count_active_children(struct prefork_pool *pfp, int *total);
+
/**
-* @brief Mark a child structure as free, based on the dead child pid.
-* This function is called when the parent gets back notice a child
-* has died through waitpid. It is critical to call this function
-* when children are reaped so that memory slots can be freed.
+* @brief Perform cleanups, like waiting (WNOHANG) dead children.
+* MUST be called regularly from the parent main loop.
*
* @param pfp The pool.
-* @param pid The child pid.
-*
-* @return True if the slot was clared. False if the pid is not listed.
*/
-bool prefork_mark_pid_dead(struct prefork_pool *pfp, pid_t pid);
+void prefork_cleanup_loop(struct prefork_pool *pfp);
/**
* @brief Inform all children that they are allowed to accept 'max' clients
diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c
index 25223c94c5..27704dab3c 100644
--- a/source3/printing/spoolssd.c
+++ b/source3/printing/spoolssd.c
@@ -524,23 +524,16 @@ static void spoolssd_sig_chld_handler(struct tevent_context *ev_ctx,
void *siginfo, void *pvt)
{
struct prefork_pool *pfp;
- pid_t pid;
- int status;
- bool ok;
int active, total;
int n, r;
pfp = talloc_get_type_abort(pvt, struct prefork_pool);
- while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
- ok = prefork_mark_pid_dead(pfp, pid);
- if (!ok) {
- DEBUG(1, ("Pid %d was not found in children pool!\n",
- (int)pid));
- }
- }
+ /* run the cleanup function to make sure all dead children are
+ * properly and timely retired. */
+ prefork_cleanup_loop(pfp);
- /* now check we do not descent below the minimum */
+ /* now check we do not descend below the minimum */
active = prefork_count_active_children(pfp, &total);
n = 0;