2014-05-16 13:48:04 +02:00
|
|
|
Based on 574634bcacb01efe15ca2742effd461a5b7afb5f Mon Sep 17 00:00:00 2001
|
|
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
|
Date: Tue, 13 May 2014 23:22:13 +0200
|
|
|
|
Subject: [PATCH] core: close socket fds asynchronously
|
|
|
|
|
|
|
|
http://lists.freedesktop.org/archives/systemd-devel/2014-April/018928.html
|
|
|
|
---
|
2014-07-01 12:11:44 +02:00
|
|
|
src/core/async.c | 24 ++++++++++++++++++++++++
|
2014-05-16 13:48:04 +02:00
|
|
|
src/core/service.c | 5 +++--
|
2014-07-01 12:11:44 +02:00
|
|
|
2 files changed, 27 insertions(+), 2 deletions(-)
|
2014-05-16 13:48:04 +02:00
|
|
|
|
|
|
|
--- src/core/service.c
|
|
|
|
+++ src/core/service.c 2014-05-16 11:41:50.150735247 +0000
|
|
|
|
@@ -25,6 +25,7 @@
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/reboot.h>
|
|
|
|
|
|
|
|
+#include "async.h"
|
|
|
|
#include "manager.h"
|
|
|
|
#include "unit.h"
|
|
|
|
#include "service.h"
|
|
|
|
@@ -240,7 +241,7 @@ static void service_close_socket_fd(Serv
|
|
|
|
if (s->socket_fd < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
- close_nointr_nofail(s->socket_fd);
|
|
|
|
+ asynchronous_close(s->socket_fd);
|
|
|
|
s->socket_fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2767,7 +2768,7 @@ static int service_deserialize_item(Unit
|
|
|
|
else {
|
|
|
|
|
|
|
|
if (s->socket_fd >= 0)
|
|
|
|
- close_nointr_nofail(s->socket_fd);
|
|
|
|
+ asynchronous_close(s->socket_fd);
|
|
|
|
s->socket_fd = fdset_remove(fds, fd);
|
|
|
|
}
|
|
|
|
} else if (streq(key, "main-exec-status-pid")) {
|
|
|
|
--- src/core/async.c
|
|
|
|
+++ src/core/async.c 2014-05-07 09:40:35.000000000 +0000
|
|
|
|
@@ -24,6 +24,7 @@
|
|
|
|
|
|
|
|
#include "async.h"
|
|
|
|
#include "log.h"
|
|
|
|
+#include "util.h"
|
|
|
|
|
|
|
|
int asynchronous_job(void* (*func)(void *p), void *arg) {
|
|
|
|
pthread_attr_t a;
|
2014-07-01 12:11:44 +02:00
|
|
|
@@ -70,3 +71,26 @@ int asynchronous_sync(void) {
|
2014-05-16 13:48:04 +02:00
|
|
|
|
|
|
|
return asynchronous_job(sync_thread, NULL);
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+static void *close_thread(void *p) {
|
2014-07-01 12:11:44 +02:00
|
|
|
+ int fd = PTR_TO_INT(p);
|
|
|
|
+ if (fd >= 0)
|
|
|
|
+ close_nointr_nofail(fd);
|
2014-05-16 13:48:04 +02:00
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int asynchronous_close(int fd) {
|
|
|
|
+ int r;
|
|
|
|
+
|
|
|
|
+ /* This is supposed to behave similar to safe_close(), but
|
|
|
|
+ * actually invoke close() asynchronously, so that it will
|
|
|
|
+ * never block. Ideally the kernel would have an API for this,
|
|
|
|
+ * but it doesn't, so we work around it, and hide this as a
|
|
|
|
+ * far away as we can. */
|
|
|
|
+
|
|
|
|
+ r = asynchronous_job(close_thread, INT_TO_PTR(fd));
|
2014-07-01 12:11:44 +02:00
|
|
|
+ if (r < 0 && fd >= 0)
|
2014-05-16 13:48:04 +02:00
|
|
|
+ close_nointr_nofail(fd);
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|