1 #include <stdio.h>
  2 #include <string.h>
  3 #include "rhttpd.h"
  4 #include "server.h"
  5 #include "client.h"
  6 
  7 static void server_read (int fd, short rh_events, void *arg);
  8 
  9 void server_init (server_t *server, rh_stat_cache_t *stat_cache,
 10                 config_t *config, handler_base_t *handler_base,
 11                 memcache_t *memcache )
 12 {
 13         memset (server, 0, sizeof(*server));
 14 
 15         TAILQ_INIT(&server->clients);
 16         
 17         rh_socket_init (&server->socket);
 18         
 19         server->config = config;
 20 
 21         server->stat_cache = stat_cache;
 22 
 23         server->handler_base = handler_base;
 24 
 25         server->memcache = memcache;
 26 
 27         rh_gmtime_init (&server->gmtime, 0);
 28 }
 29 
 30 void server_destroy (server_t *server)
 31 {
 32         client_t        *client;
 33         
 34         rh_socket_close (&server->socket);
 35 
 36         while (!TAILQ_EMPTY(&server->clients)) {
 37 
 38                 client = TAILQ_FIRST(&server->clients);
 39                 
 40                 TAILQ_REMOVE(&server->clients, client, clients);
 41 
 42                 client_free (client);
 43         }
 44 
 45         if (server->handler_error) {
 46                 handler_free (server->handler_error);
 47                 server->handler_error = NULL;
 48         }
 49         
 50         if (server->handler_accesslog) {
 51                 handler_free (server->handler_accesslog);
 52                 server->handler_accesslog = NULL;
 53         }
 54 }
 55 
 56 static void server_read (int fd, short rh_events, void *arg)
 57 {
 58         struct server *server = arg;
 59         
 60 #if 0
 61         printf ("%s (%3d, %hd, %p)\n", __FUNCTION__, fd, rh_events, arg);
 62 #endif
 63         
 64         rh_gmtime_update (&server->gmtime, server->ev_base->time);
 65                 
 66         for (;;) {
 67                 struct rh_socket        client_socket;
 68                 struct client           *client;
 69                 
 70                 if (-1 == rh_socket_accept (&server->socket, &client_socket))
 71                         return;
 72 
 73                 client = memcache_pop (server->memcache, sizeof(*client));
 74                 if (NULL == client) {
 75                         rh_socket_close(&client_socket);
 76                         return;
 77                 }
 78 
 79                 if (client_init (client, &client_socket, server)) {
 80                         client_free(client);
 81                         return;
 82                 }
 83         }
 84 }
 85 
 86 int server_bind (server_t *server, struct rh_event_base *ev_base,
 87                 const char *hostname, unsigned short port)
 88 {
 89         if (-1 == rh_socket_create (&server->socket, AF_INET, SOCK_STREAM, 0))
 90                 goto error_out;
 91 
 92         if (-1 == rh_socket_set (&server->socket, RH_SOCKET_NONBLOCK))
 93                 goto error_out;
 94         
 95         if (-1 == rh_socket_set (&server->socket, RH_SOCKET_REUSEADDR))
 96                 goto error_out;
 97         
 98         if (-1 == rh_socket_set_addr (&server->socket, port))
 99                 goto error_out;
100 
101         if (-1 == rh_socket_bind (&server->socket))
102                 goto error_out;
103         
104         if (-1 == rh_socket_listen (&server->socket, RHTTPD_BACKLOG))
105                 goto error_out;
106         
107         server->ev_base = ev_base;
108         
109         rh_event_set (  &server->socket.event_read,
110                         server->ev_base,
111                         server->socket.fd,
112                         RH_EVENT_READ,// | RH_EVENT_ET,
113                         server_read,
114                         server);
115 
116         if (-1 == rh_event_add (&server->socket.event_read))
117                 goto error_out;
118         
119         return 0;
120 
121 error_out:
122         rh_socket_close (&server->socket);
123         return -1;
124 }


syntax highlighted by Code2HTML, v. 0.9.1