diff options
author | LAN-TW <lantw44@gmail.com> | 2014-01-14 16:47:54 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2014-01-14 16:47:54 +0800 |
commit | 08b63dcd438ee4ec68fe9eb61b6cd42ee6684963 (patch) | |
tree | 4f3704448c7330f0a8c383e6193af6e5a40ad2cb | |
parent | d24aa7d6ceac4914906ce76aa729fd5c7011eb3d (diff) | |
download | sp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.tar.gz sp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.tar.zst sp2013-08b63dcd438ee4ec68fe9eb61b6cd42ee6684963.zip |
HW4: 準備處理 connection
-rw-r--r-- | hw4/Makefile.am | 2 | ||||
-rw-r--r-- | hw4/chttpd/chttpd-conn.c | 60 | ||||
-rw-r--r-- | hw4/chttpd/chttpd-conn.h | 30 | ||||
-rw-r--r-- | hw4/chttpd/chttpd-server.c | 35 |
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); } |