dovecot-2.0: master: Try to read multiple status updates in a si...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Mar 4 20:19:06 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/43a278ca5354
changeset: 10832:43a278ca5354
user: Timo Sirainen <tss at iki.fi>
date: Thu Mar 04 19:59:39 2010 +0200
description:
master: Try to read multiple status updates in a single read().
diffstat:
src/master/service-monitor.c | 69 +++++++++++++++++++---------------
1 files changed, 38 insertions(+), 31 deletions(-)
diffs (107 lines):
diff -r c691706eee06 -r 43a278ca5354 src/master/service-monitor.c
--- a/src/master/service-monitor.c Thu Mar 04 16:52:11 2010 +0200
+++ b/src/master/service-monitor.c Thu Mar 04 19:59:39 2010 +0200
@@ -100,39 +100,19 @@
service_login_notify(service, FALSE);
}
-static void service_status_input(struct service *service)
+static void
+service_status_input_one(struct service *service,
+ const struct master_status *status)
{
- struct master_status status;
struct service_process *process;
- ssize_t ret;
- status.pid = 0;
- ret = read(service->status_fd[0], &status, sizeof(status));
- switch (ret) {
- case 0:
- service_error(service, "read(status) failed: EOF");
- service_monitor_stop(service);
- return;
- case -1:
- service_error(service, "read(status) failed: %m");
- service_monitor_stop(service);
- return;
- default:
- service_error(service, "child %s sent partial status update "
- "(%d bytes)", dec2str(status.pid), (int)ret);
- return;
-
- case sizeof(status):
- break;
- }
-
- process = hash_table_lookup(service_pids, &status.pid);
+ process = hash_table_lookup(service_pids, &status->pid);
if (process == NULL) {
/* we've probably wait()ed it away already. ignore */
return;
}
- if (process->uid != status.uid || process->service != service) {
+ if (process->uid != status->uid || process->service != service) {
/* a) Process was closed and another process was created with
the same PID, but we're still receiving status update from
the old process.
@@ -143,7 +123,7 @@
are already more serious problems if someone is able to do
this.. */
service_error(service, "Ignoring invalid update from child %s "
- "(UID=%u)", dec2str(status.pid), status.uid);
+ "(UID=%u)", dec2str(status->pid), status->uid);
return;
}
@@ -152,17 +132,44 @@
timeout_remove(&process->to_status);
}
- if (process->available_count == status.available_count)
+ if (process->available_count == status->available_count)
return;
- if (process->available_count > status.available_count) {
+ if (process->available_count > status->available_count) {
/* process started servicing some more clients */
- service_status_more(process, &status);
+ service_status_more(process, status);
} else {
/* process finished servicing some clients */
- service_status_less(process, &status);
+ service_status_less(process, status);
}
- process->available_count = status.available_count;
+ process->available_count = status->available_count;
+}
+
+static void service_status_input(struct service *service)
+{
+ struct master_status status[1024/sizeof(struct master_status)];
+ unsigned int i, count;
+ ssize_t ret;
+
+ ret = read(service->status_fd[0], &status, sizeof(status));
+ if (ret <= 0) {
+ if (ret == 0)
+ service_error(service, "read(status) failed: EOF");
+ else
+ service_error(service, "read(status) failed: %m");
+ service_monitor_stop(service);
+ return;
+ }
+
+ if ((ret % sizeof(struct master_status)) != 0) {
+ service_error(service, "service sent partial status update "
+ "(%d bytes)", (int)ret);
+ return;
+ }
+
+ count = ret / sizeof(struct master_status);
+ for (i = 0; i < count; i++)
+ service_status_input_one(service, &status[i]);
}
static void service_monitor_throttle(struct service *service)
More information about the dovecot-cvs
mailing list