diff --git a/examples/chat.c b/examples/chat.c index c2bf1bfa..39fa7619 100644 --- a/examples/chat.c +++ b/examples/chat.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "mongoose.h" @@ -148,6 +149,15 @@ static void ajax_get_messages(struct mg_connection *conn, } } +// Allocate new message. Caller must hold the lock. +static struct message *new_message(void) { + static int size = sizeof(messages) / sizeof(messages[0]); + struct message *message = &messages[last_message_id % size]; + message->id = last_message_id++; + message->timestamp = time(0); + return message; +} + // A handler for the /ajax/send_message endpoint. static void ajax_send_message(struct mg_connection *conn, const struct mg_request_info *request_info) { @@ -164,15 +174,12 @@ static void ajax_send_message(struct mg_connection *conn, // We have a message to store. Write-lock the ringbuffer, // grab the next message and copy data into it. pthread_rwlock_wrlock(&rwlock); - message = &messages[last_message_id % - (sizeof(messages) / sizeof(messages[0]))]; + message = new_message(); // TODO(lsm): JSON-encode all text strings session = get_session(conn); assert(session != NULL); strlcpy(message->text, text, sizeof(text)); strlcpy(message->user, session->user, sizeof(message->user)); - message->timestamp = time(0); - message->id = last_message_id++; pthread_rwlock_unlock(&rwlock); } @@ -231,6 +238,20 @@ static void generate_session_id(char *buf, const char *random, mg_md5(buf, random, user, remote_port, remote_ip, NULL); } +static void send_server_message(const char *fmt, ...) { + va_list ap; + struct message *message; + + pthread_rwlock_wrlock(&rwlock); + message = new_message(); + message->user[0] = '\0'; // Empty user indicates server message + va_start(ap, fmt); + vsnprintf(message->text, sizeof(message->text), fmt, ap); + va_end(ap); + + pthread_rwlock_unlock(&rwlock); +} + // A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. static void authorize(struct mg_connection *conn, @@ -259,8 +280,7 @@ static void authorize(struct mg_connection *conn, snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user, request_info); - printf("New session, user: %s, id: %s, redirecting to %s\n", - session->user, session->session_id, original_url); + send_server_message("<%s> joined", session->user); mg_printf(conn, "HTTP/1.1 302 Found\r\n" "Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID "Set-Cookie: user=%s\r\n" // Set user, needed by Javascript code @@ -290,9 +310,6 @@ static int is_authorized(const struct mg_connection *conn, authorized = 1; } } - // Printing while holding the lock is a bad idea. - printf("session: %s, uri: %s, authorized: %s\n", - session->session_id, request_info->uri, authorized ? "yes" : "no"); pthread_rwlock_unlock(&rwlock); return authorized;