introduced a logging thread
This commit is contained in:
parent
b2697e7cb8
commit
88f6a30274
|
@ -26,9 +26,12 @@ struct server {
|
|||
GHashTable *options;
|
||||
gpointer *option_def_values;
|
||||
|
||||
gboolean exiting;
|
||||
GMutex *mutex;
|
||||
|
||||
GArray *logs;
|
||||
GAsyncQueue *log_queue;
|
||||
GThread *log_thread;
|
||||
};
|
||||
|
||||
struct connection {
|
||||
|
|
|
@ -39,8 +39,13 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* initialize threading */
|
||||
g_thread_init(NULL);
|
||||
|
||||
srv = server_new();
|
||||
|
||||
log_init(srv);
|
||||
|
||||
/* if no path is specified for the config, read lighttpd.conf from current directory */
|
||||
if (config_path == NULL)
|
||||
config_path = "lighttpd.conf";
|
||||
|
@ -64,5 +69,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
TRACE("%s", "Test!");
|
||||
|
||||
g_thread_join(srv->log_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
105
src/log.c
105
src/log.c
|
@ -33,11 +33,9 @@ int log_write(server* UNUSED_PARAM(srv), connection* UNUSED_PARAM(con), const ch
|
|||
gboolean log_write_(server *srv, connection *con, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
GString *log_line;
|
||||
static GStaticMutex log_mutex = G_STATIC_MUTEX_INIT;
|
||||
log_t *log;
|
||||
guint log_ndx;
|
||||
gssize bytes_written;
|
||||
gssize write_res;
|
||||
log_entry_t *log_entry;
|
||||
|
||||
if (con != NULL) {
|
||||
/* get log index from connection */
|
||||
|
@ -73,36 +71,11 @@ gboolean log_write_(server *srv, connection *con, const char *fmt, ...) {
|
|||
|
||||
g_string_append_len(log_line, CONST_STR_LEN("\r\n"));
|
||||
|
||||
bytes_written = 0;
|
||||
|
||||
/* lock to ensure that multiple threads don't mess up the logs */
|
||||
g_static_mutex_lock(&log_mutex);
|
||||
while (bytes_written < (gssize)log_line->len) {
|
||||
write_res = write(log->fd, log_line->str + bytes_written, log_line->len - bytes_written);
|
||||
|
||||
assert(write_res <= (gssize) log_line->len);
|
||||
|
||||
/* write() failed, check why */
|
||||
if (write_res == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the error is serious, unlock mutex and return as we can't seem to write to the log */
|
||||
g_static_mutex_unlock(&log_mutex);
|
||||
g_string_free(log_line, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
bytes_written += write_res;
|
||||
assert(bytes_written <= (gssize) log_line->len);
|
||||
}
|
||||
}
|
||||
|
||||
g_static_mutex_unlock(&log_mutex);
|
||||
g_string_free(log_line, TRUE);
|
||||
log_entry = g_slice_new(log_entry_t);
|
||||
log_entry->fd = log->fd;
|
||||
log_entry->msg = log_line;
|
||||
g_async_queue_push(srv->log_queue, log_entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -132,3 +105,71 @@ void log_free(log_t *log) {
|
|||
g_mutex_free(log->mutex);
|
||||
g_string_free(log->lastmsg, TRUE);
|
||||
}
|
||||
|
||||
|
||||
gpointer log_thread(server *srv) {
|
||||
GAsyncQueue *queue;
|
||||
gboolean exiting;
|
||||
log_entry_t *log_entry;
|
||||
GTimeVal *timeout;
|
||||
gssize bytes_written;
|
||||
gssize write_res;
|
||||
|
||||
queue = srv->log_queue;
|
||||
|
||||
while (TRUE) {
|
||||
/* check if we need to exit */
|
||||
g_mutex_lock(srv->mutex);
|
||||
exiting = srv->exiting;
|
||||
g_mutex_unlock(srv->mutex);
|
||||
if (exiting)
|
||||
break;
|
||||
|
||||
/* 1 second timeout */
|
||||
g_get_current_time(timeout);
|
||||
g_time_val_add(timeout, 1000 * 1000 * 1);
|
||||
log_entry = g_async_queue_timed_pop(srv->log_queue, timeout);
|
||||
|
||||
g_print("log_thread ping\n");
|
||||
|
||||
if (log_entry == NULL)
|
||||
continue;
|
||||
|
||||
while (bytes_written < (gssize)log_entry->msg->len) {
|
||||
write_res = write(log_entry->fd, log_entry->msg->str + bytes_written, log_entry->msg->len - bytes_written);
|
||||
|
||||
assert(write_res <= (gssize) log_entry->msg->len);
|
||||
|
||||
/* write() failed, check why */
|
||||
if (write_res == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bytes_written += write_res;
|
||||
assert(bytes_written <= (gssize) log_entry->msg->len);
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free(log_entry->msg, TRUE);
|
||||
g_slice_free(log_entry_t, log_entry);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void log_init(server *srv) {
|
||||
GError *err = NULL;
|
||||
|
||||
srv->log_thread = g_thread_create((GThreadFunc)log_thread, srv, TRUE, &err);
|
||||
|
||||
if (srv->log_thread == NULL) {
|
||||
g_printerr("could not create loggin thread: %s\n", err->message);
|
||||
assert(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
10
src/log.h
10
src/log.h
|
@ -49,6 +49,9 @@ LI_API int log_write(server *srv, connection *con, const char *fmt, ...) __ATTRI
|
|||
struct log_t;
|
||||
typedef struct log_t log_t;
|
||||
|
||||
struct log_entry_t;
|
||||
typedef struct log_entry_t log_entry_t;
|
||||
|
||||
struct log_t {
|
||||
gint fd;
|
||||
GMutex *mutex;
|
||||
|
@ -56,7 +59,14 @@ struct log_t {
|
|||
guint lastmsg_count;
|
||||
};
|
||||
|
||||
struct log_entry_t {
|
||||
gint fd;
|
||||
GString *msg;
|
||||
};
|
||||
|
||||
log_t *log_new(const gchar* filename);
|
||||
void log_free(log_t *log);
|
||||
gpointer log_thread(server *srv);
|
||||
void log_init(server *srv);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,8 @@ server* server_new() {
|
|||
srv->mutex = g_mutex_new();
|
||||
|
||||
srv->logs = g_array_new(FALSE, FALSE, sizeof(log_t));
|
||||
srv->log_queue = g_async_queue_new();
|
||||
srv->exiting = FALSE;
|
||||
|
||||
return srv;
|
||||
}
|
||||
|
@ -29,5 +31,7 @@ void server_free(server* srv) {
|
|||
}
|
||||
g_array_free(srv->logs, TRUE);
|
||||
|
||||
g_async_queue_unref(srv->log_queue);
|
||||
|
||||
g_slice_free(server, srv);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#import Object, Params, os, sys
|
||||
import Options
|
||||
|
||||
common_uselib = 'glib '
|
||||
common_uselib = 'glib gthread'
|
||||
|
||||
common_source='''
|
||||
actions.c
|
||||
|
|
4
wscript
4
wscript
|
@ -382,6 +382,10 @@ def configure(conf):
|
|||
conf.env['CPPPATH_glib'] += [ incdir+'/glib-2.0/', incdir + '/glib-2.0/include/' ]
|
||||
CHECK_INCLUDE_FILES(conf, "glib.h", "HAVE_GLIB_H", uselib = 'glib', use = ['glib'], mandatory = 1)
|
||||
|
||||
PKGCONFIG(conf, "gthread-2.0", uselib = 'gthread', mandatory = 1)
|
||||
incdir = conf.env['CPPPATH_gthread'][0]
|
||||
conf.env['CPPPATH_gthread'] += [ incdir+'/glib-2.0/', incdir + '/glib-2.0/include/' ]
|
||||
|
||||
#if opts.libfcgi:
|
||||
#CHECK_INCLUDE_FILES(conf, "fastcgi.h", "HAVE_FASTCGI_H", uselib = 'libfcgi')
|
||||
#if not conf.is_defined("HAVE_FASTCGI_H"):
|
||||
|
|
Loading…
Reference in New Issue