summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2014-01-14 16:47:54 +0800
committerLAN-TW <lantw44@gmail.com>2014-01-14 16:47:54 +0800
commit08b63dcd438ee4ec68fe9eb61b6cd42ee6684963 (patch)
tree4f3704448c7330f0a8c383e6193af6e5a40ad2cb
parentd24aa7d6ceac4914906ce76aa729fd5c7011eb3d (diff)
downloadsp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.tar.gz
sp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.tar.zst
sp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.zip
HW4: 準備處理 connection
-rw-r--r--hw4/Makefile.am2
-rw-r--r--hw4/chttpd/chttpd-conn.c60
-rw-r--r--hw4/chttpd/chttpd-conn.h30
-rw-r--r--hw4/chttpd/chttpd-server.c35
4 files changed, 126 insertions, 1 deletions
diff --git a/hw4/Makefile.am b/hw4/Makefile.am
index 898a3b9..62f22d8 100644
--- a/hw4/Makefile.am
+++ b/hw4/Makefile.am
@@ -25,6 +25,8 @@ cgish_httpd_SOURCES = \
chttpd/chttpd-socket.c \
chttpd/chttpd-server.h \
chttpd/chttpd-server.c \
+ chttpd/chttpd-conn.h \
+ chttpd/chttpd-conn.c \
$(NULL)
cgish_httpd_CFLAGS = -pthread -I$(top_srcdir)/l4basic -I$(top_srcdir)/chttpd
cgish_httpd_LDADD = $(top_builddir)/libl4basic.a
diff --git a/hw4/chttpd/chttpd-conn.c b/hw4/chttpd/chttpd-conn.c
new file mode 100644
index 0000000..494742d
--- /dev/null
+++ b/hw4/chttpd/chttpd-conn.c
@@ -0,0 +1,60 @@
+/* b01902062 藍挺瑋 */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "chttpd-conn.h"
+#include "chttpd-log.h"
+#include "chttpd-server.h"
+#include <l4list.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#define CHTTPD_CONN_THREAD_INIT \
+ ChttpdConn* conn = ptr_to_ChttpdConn; \
+ ChttpdServer* server = conn->server; \
+ ChttpdLog* hlog = conn->hlog
+
+#define CHTTPD_CONN_THREAD_DESTROY \
+ chttpd_log_write (hlog, "[%4llu] terminated", conn->id); \
+ pthread_rwlock_wrlock (&server->lock); \
+ lbs_list_remove (server->conn, conn->conn_node); \
+ pthread_rwlock_unlock (&server->lock); \
+ return NULL
+
+
+void* chttpd_conn_admin (void* ptr_to_ChttpdConn) {
+ CHTTPD_CONN_THREAD_INIT;
+
+ CHTTPD_CONN_THREAD_DESTROY;
+}
+
+void* chttpd_conn_http (void* ptr_to_ChttpdConn) {
+ CHTTPD_CONN_THREAD_INIT;
+
+ CHTTPD_CONN_THREAD_DESTROY;
+}
+
+void chttpd_conn_ctor (void* conn_generic, unsigned long long id, int connfd,
+ ChttpdLog* hlog, ChttpdServer* server, LbsListMeta* slist) {
+
+ ChttpdConn* conn = conn_generic;
+ conn->id = id;
+ conn->connfd = connfd;
+ conn->hlog = chttpd_log_ref (hlog);
+ conn->server = server;
+ conn->slist = slist;
+ pthread_rwlock_init (&conn->lock, NULL);
+ conn->pid = -1;
+}
+
+void chttpd_conn_dtor (void* conn_generic) {
+ ChttpdConn* conn = conn_generic;
+ close (conn->connfd);
+ chttpd_log_unref (conn->hlog);
+ pthread_rwlock_wrlock (&conn->lock);
+ pthread_rwlock_unlock (&conn->lock);
+ pthread_rwlock_destroy (&conn->lock);
+ free (conn);
+}
diff --git a/hw4/chttpd/chttpd-conn.h b/hw4/chttpd/chttpd-conn.h
new file mode 100644
index 0000000..d3e1f54
--- /dev/null
+++ b/hw4/chttpd/chttpd-conn.h
@@ -0,0 +1,30 @@
+#ifndef CHTTPD_CONN_H
+#define CHTTPD_CONN_H
+
+#include "chttpd-log.h"
+#include "chttpd-server.h"
+#include <l4list.h>
+#include <sys/types.h>
+
+typedef struct {
+ /* read-only */
+ unsigned long long id;
+ int connfd;
+ ChttpdLog* hlog;
+ ChttpdServer *server;
+ LbsListMeta *slist;
+ LbsList* conn_node; /* reference to the corresponding node in server->conn */
+
+ /* read-write and lock */
+ pthread_rwlock_t lock;
+ pid_t pid;
+} ChttpdConn;
+
+void* chttpd_conn_admin (void* ptr_to_ChttpdConn); /* TODO: implement this */
+void* chttpd_conn_http (void* ptr_to_ChttpdConn);
+
+void chttpd_conn_ctor (void* conn_generic, unsigned long long id, int connfd,
+ ChttpdLog* hlog, ChttpdServer* server, LbsListMeta* slist);
+void chttpd_conn_dtor (void* conn_generic);
+
+#endif /* CHTTTP_CONN_H */
diff --git a/hw4/chttpd/chttpd-server.c b/hw4/chttpd/chttpd-server.c
index aab0839..0fe1576 100644
--- a/hw4/chttpd/chttpd-server.c
+++ b/hw4/chttpd/chttpd-server.c
@@ -7,6 +7,7 @@
#include "chttpd-log.h"
#include "chttpd-server.h"
#include "chttpd-socket.h"
+#include "chttpd-conn.h"
#include <l4list.h>
#include <l4str.h>
#include <l4posix.h>
@@ -263,6 +264,10 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) {
sigaddset (&crit_mask, SIGHUP);
sigaddset (&crit_mask, SIGUSR2);
+ pthread_attr_t padetach;
+ pthread_attr_init (&padetach);
+ pthread_attr_setdetachstate (&padetach, PTHREAD_CREATE_DETACHED);
+
struct pollfd* pfds = NULL;
nfds_t nfds = 0;
@@ -428,11 +433,39 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) {
"accepted", count, peername);
free (peername);
+ /* Note: the callee should free the object! */
+ ChttpdConn* conn = xmalloc (sizeof (ChttpdConn));
+ chttpd_conn_ctor (conn, count, connfd, hlog, server, slist);
+ pthread_rwlock_wrlock (&server->lock);
+ LbsList* node = lbs_list_push_back (server->conn, conn, NULL);
+ pthread_rwlock_unlock (&server->lock);
+ conn->conn_node = node;
+
+ pthread_t ptid;
+ int pterr;
+ if (server->attr_admin) {
+ pterr = pthread_create (&ptid, &padetach,
+ chttpd_conn_admin, conn);
+ } else {
+ pterr = pthread_create (&ptid, &padetach,
+ chttpd_conn_http, conn);
+ }
+
+ if (pterr != 0) {
+ chttpd_log_write (hlog, "[main] cannot create a thread for"
+ "connection %llu: %s", count,
+ get_errmsg (pterr, errmsg, ERRLEN));
+ pthread_rwlock_wrlock (&server->lock);
+ lbs_list_remove (server->conn, node);
+ pthread_rwlock_unlock (&server->lock);
+ }
+
}
}
}
free (pfds);
+ pthread_attr_destroy (&padetach);
}
#undef ERRLEN
@@ -441,7 +474,7 @@ void chttpd_server_ctor (void* server_generic, ChttpdLog* hlog, bool is_admin) {
server->attr_admin = is_admin;
server->attr_close = false;
server->hlog = chttpd_log_ref (hlog);
- server->conn = lbs_list_meta_new (NULL);
+ server->conn = lbs_list_meta_new (chttpd_conn_dtor);
pthread_rwlock_init (&server->lock, NULL);
}