[FZH] 很好,写好了一个 PATCH
microcai
microcai在fedoraproject.org
星期日 四月 24 12:23:20 UTC 2011
恩,有事情做了。写了个小 PATCH 给 gnome 了。
PS, 参考我上一个邮件。
主要是自己用 libsoup 写 http server , 可惜不能用 xinetd 或者 systemd 做
到按需加载。于是写了个 patch 实现它。提交上去了,不知道反省如何 ;)
>From 77eb437d5bcb745e75d14627f3d24085f60682a2 Mon Sep 17 00:00:00 2001
From: microcai <microcai在fedoraproject.org>
Date: Sun, 24 Apr 2011 20:10:58 +0800
Subject: [PATCH] This make libsoup based app systemd socket activation
capable. First, construt soupsocket, then manully call it
with soup_socket_listen_fd(), then pass soupsocket to
soup_server_new.
This is maybe a suggestion, you guys may have better idea/API.
But the idea is simple, make libsoup based application able to
do systemd socket activation, of Xinetd activation.
---
libsoup/soup-server.c | 33 +++++++++++++++++++++++++--------
libsoup/soup-server.h | 1 +
libsoup/soup-socket.c | 49
+++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index d56efd1..1829f45 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -130,6 +130,7 @@ enum {
PROP_ASYNC_CONTEXT,
PROP_RAW_PATHS,
PROP_SERVER_HEADER,
+ PROP_LISTEN_SOCKET,
LAST_PROP
};
@@ -446,6 +447,14 @@ soup_server_class_init (SoupServerClass *server_class)
"Server header",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class, PROP_LISTEN_SOCKET,
+ g_param_spec_object (SOUP_SERVER_LISTEN_SOCKET,
+ "Listen socket",
+ "Listen socket",
+ SOUP_TYPE_SOCKET,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
static GObject *
@@ -478,14 +487,16 @@ constructor (GType type,
}
}
- priv->listen_sock =
- soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->interface,
- SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
- SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
- NULL);
- if (!soup_socket_listen (priv->listen_sock)) {
- g_object_unref (server);
- return NULL;
+ if(!priv->listen_sock){
+ priv->listen_sock =
+ soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->interface,
+ SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
+ SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
+ NULL);
+ if (!soup_socket_listen (priv->listen_sock)) {
+ g_object_unref (server);
+ return NULL;
+ }
}
/* Re-resolve the interface address, in particular in case
@@ -548,6 +559,9 @@ set_property (GObject *object, guint prop_id,
} else
priv->server_header = g_strdup (header);
break;
+ case PROP_LISTEN_SOCKET:
+ priv->listen_sock = g_value_get_object(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -582,6 +596,9 @@ get_property (GObject *object, guint prop_id,
case PROP_SERVER_HEADER:
g_value_set_string (value, priv->server_header);
break;
+ case PROP_LISTEN_SOCKET:
+ g_value_set_object(value,priv->listen_sock);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/libsoup/soup-server.h b/libsoup/soup-server.h
index 4ea17ad..3f630da 100644
--- a/libsoup/soup-server.h
+++ b/libsoup/soup-server.h
@@ -63,6 +63,7 @@ typedef void (*SoupServerCallback) (SoupServer
*server,
#define SOUP_SERVER_ASYNC_CONTEXT "async-context"
#define SOUP_SERVER_RAW_PATHS "raw-paths"
#define SOUP_SERVER_SERVER_HEADER "server-header"
+#define SOUP_SERVER_LISTEN_SOCKET "listen-socket"
SoupServer *soup_server_new (const char
*optname1,
...) G_GNUC_NULL_TERMINATED;
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 8d11841..ffbc883 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -854,6 +854,55 @@ soup_socket_listen (SoupSocket *sock)
return FALSE;
}
+
+/**
+ * soup_socket_listen_fd:
+ * @sock: a server #SoupSocket (which must not already be connected or
+ * listening)
+ * @fd: a native socket fd, that is already listen on an address
+ *
+ * Makes @sock start listening on the passing fd
+ *
+ **/
+void
+soup_socket_listen_fd (SoupSocket *sock,int fd)
+
+{
+ SoupSocketPrivate *priv;
+
+ g_return_if_fail (SOUP_IS_SOCKET (sock));
+ priv = SOUP_SOCKET_GET_PRIVATE (sock);
+ g_return_if_fail (priv->gsock == NULL);
+
+ priv->is_server = TRUE;
+
+ /* @local_addr may have its port set to 0. So we intentionally
+ * don't store it in priv->local_addr, so that if the
+ * caller calls soup_socket_get_local_address() later, we'll
+ * have to make a new addr by calling getsockname(), which
+ * will have the right port number.
+ */
+
+ priv->gsock = g_socket_new_from_fd(fd,NULL);
+
+ if (!priv->gsock)
+ goto cant_listen;
+
+ finish_socket_setup (priv);
+
+ /* Force local_addr to be re-resolved now */
+ g_object_unref (priv->local_addr);
+ priv->local_addr = NULL;
+
+ priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
+ listen_watch, sock,
+ NULL);
+ return ;
+
+ cant_listen:
+ if (priv->conn)
+ disconnect_internal (sock);
+}
static void
soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
gpointer sock)
关于邮件列表 Chinese 的更多信息