mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
check rvalues from pthread_mutex_ operations in examples
This commit is contained in:
@@ -187,8 +187,9 @@
|
|||||||
" function window_onload(event)\n" \
|
" function window_onload(event)\n" \
|
||||||
" {\n" \
|
" {\n" \
|
||||||
" /* Determine the base url (for http:/" "/ this is ws:/" "/ for https:/" \
|
" /* Determine the base url (for http:/" "/ this is ws:/" "/ for https:/" \
|
||||||
"/ this must be wss:/" "/) */\n" \
|
"/ this must be wss:/" "/) */\n" \
|
||||||
" baseUrl = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + ':/" "/' + window.location.host + '/ChatServerWebSocket';\n" \
|
" baseUrl = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + ':/" \
|
||||||
|
"/' + window.location.host + '/ChatServerWebSocket';\n" \
|
||||||
" chat_generate();\n" \
|
" chat_generate();\n" \
|
||||||
" chat_connect();\n" \
|
" chat_connect();\n" \
|
||||||
" }\n" \
|
" }\n" \
|
||||||
@@ -586,7 +587,7 @@
|
|||||||
" let message = [ ];\n" \
|
" let message = [ ];\n" \
|
||||||
" /* message type */ \n" \
|
" /* message type */ \n" \
|
||||||
" let j = 0;\n" \
|
" let j = 0;\n" \
|
||||||
" let i = byteData.indexOf(0x7C, j); /* | = 0x7C;*/ \n"\
|
" let i = byteData.indexOf(0x7C, j); /* | = 0x7C;*/ \n" \
|
||||||
" if(i < 0)\n" \
|
" if(i < 0)\n" \
|
||||||
" return;\n" \
|
" return;\n" \
|
||||||
" message.push(decoder.decode(byteData.slice(0, i)));\n" \
|
" message.push(decoder.decode(byteData.slice(0, i)));\n" \
|
||||||
@@ -737,28 +738,28 @@ send_all (struct ConnectedUser *cu,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
size_t off;
|
size_t off;
|
||||||
|
|
||||||
if (0 == pthread_mutex_lock (&cu->send_mutex))
|
if (0 != pthread_mutex_lock (&cu->send_mutex))
|
||||||
|
abort ();
|
||||||
|
for (off = 0; off < len; off += ret)
|
||||||
{
|
{
|
||||||
for (off = 0; off < len; off += ret)
|
ret = send (cu->fd,
|
||||||
|
&buf[off],
|
||||||
|
(int) (len - off),
|
||||||
|
0);
|
||||||
|
if (0 > ret)
|
||||||
{
|
{
|
||||||
ret = send (cu->fd,
|
if (EAGAIN == errno)
|
||||||
&buf[off],
|
|
||||||
(int) (len - off),
|
|
||||||
0);
|
|
||||||
if (0 > ret)
|
|
||||||
{
|
{
|
||||||
if (EAGAIN == errno)
|
ret = 0;
|
||||||
{
|
continue;
|
||||||
ret = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (0 == ret)
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&cu->send_mutex);
|
if (0 == ret)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (0 != pthread_mutex_unlock (&cu->send_mutex))
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -806,7 +807,7 @@ chat_addmessage (size_t from_user_id,
|
|||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
{
|
{
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
return 1;
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the new message to the global message list */
|
/* add the new message to the global message list */
|
||||||
@@ -819,7 +820,8 @@ chat_addmessage (size_t from_user_id,
|
|||||||
{
|
{
|
||||||
free (message);
|
free (message);
|
||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
messages_[message_count] = message;
|
messages_[message_count] = message;
|
||||||
@@ -834,7 +836,8 @@ chat_addmessage (size_t from_user_id,
|
|||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
{
|
{
|
||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -854,7 +857,7 @@ chat_clearmessages (int needs_lock)
|
|||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
{
|
{
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
return 1;
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the clean counter and check whether we need cleaning */
|
/* update the clean counter and check whether we need cleaning */
|
||||||
@@ -864,7 +867,8 @@ chat_clearmessages (int needs_lock)
|
|||||||
/* no cleanup required */
|
/* no cleanup required */
|
||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -916,7 +920,8 @@ chat_clearmessages (int needs_lock)
|
|||||||
/* unlock the global mutex if needed */
|
/* unlock the global mutex if needed */
|
||||||
if (0 != needs_lock)
|
if (0 != needs_lock)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -947,10 +952,7 @@ chat_adduser (struct ConnectedUser *cu)
|
|||||||
|
|
||||||
/* lock the mutex */
|
/* lock the mutex */
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
free (data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* inform the other chat users about the new user */
|
/* inform the other chat users about the new user */
|
||||||
if (0 != chat_addmessage (0,
|
if (0 != chat_addmessage (0,
|
||||||
0,
|
0,
|
||||||
@@ -960,7 +962,8 @@ chat_adduser (struct ConnectedUser *cu)
|
|||||||
0))
|
0))
|
||||||
{
|
{
|
||||||
free (data);
|
free (data);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
free (data);
|
free (data);
|
||||||
@@ -973,7 +976,8 @@ chat_adduser (struct ConnectedUser *cu)
|
|||||||
if (NULL == users_)
|
if (NULL == users_)
|
||||||
{
|
{
|
||||||
/* realloc failed */
|
/* realloc failed */
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
users_[user_count] = cu;
|
users_[user_count] = cu;
|
||||||
@@ -985,7 +989,8 @@ chat_adduser (struct ConnectedUser *cu)
|
|||||||
cu->next_message_index = message_count;
|
cu->next_message_index = message_count;
|
||||||
|
|
||||||
/* unlock the mutex */
|
/* unlock the mutex */
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,10 +1019,7 @@ chat_removeuser (struct ConnectedUser *cu)
|
|||||||
|
|
||||||
/* lock the mutex */
|
/* lock the mutex */
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
free (data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* inform the other chat users that the user is gone */
|
/* inform the other chat users that the user is gone */
|
||||||
int got_error = 0;
|
int got_error = 0;
|
||||||
if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
|
if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
|
||||||
@@ -1045,7 +1047,8 @@ chat_removeuser (struct ConnectedUser *cu)
|
|||||||
got_error = 1;
|
got_error = 1;
|
||||||
|
|
||||||
/* unlock the mutex */
|
/* unlock the mutex */
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
|
||||||
return got_error;
|
return got_error;
|
||||||
}
|
}
|
||||||
@@ -1066,9 +1069,7 @@ chat_renameuser (struct ConnectedUser *cu,
|
|||||||
{
|
{
|
||||||
/* lock the mutex */
|
/* lock the mutex */
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check whether the name is already in use */
|
/* check whether the name is already in use */
|
||||||
for (size_t i = 0; i < user_count; ++i)
|
for (size_t i = 0; i < user_count; ++i)
|
||||||
@@ -1078,7 +1079,8 @@ chat_renameuser (struct ConnectedUser *cu,
|
|||||||
if ((users[i]->user_name_len == new_name_len) &&
|
if ((users[i]->user_name_len == new_name_len) &&
|
||||||
(0 == strcasecmp (users[i]->user_name, new_name)))
|
(0 == strcasecmp (users[i]->user_name, new_name)))
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1101,7 +1103,8 @@ chat_renameuser (struct ConnectedUser *cu,
|
|||||||
if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
|
if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
|
||||||
{
|
{
|
||||||
free (data);
|
free (data);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
free (data);
|
free (data);
|
||||||
@@ -1112,7 +1115,8 @@ chat_renameuser (struct ConnectedUser *cu,
|
|||||||
cu->user_name_len = new_name_len;
|
cu->user_name_len = new_name_len;
|
||||||
|
|
||||||
/* unlock the mutex */
|
/* unlock the mutex */
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1411,48 +1415,39 @@ connecteduser_parse_received_websocket_stream (struct ConnectedUser *cu,
|
|||||||
case 3:
|
case 3:
|
||||||
/* ping */
|
/* ping */
|
||||||
{
|
{
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
/* check whether the to_user exists */
|
||||||
|
struct ConnectedUser *ping_user = NULL;
|
||||||
|
for (size_t k = 0; k < user_count; ++k)
|
||||||
{
|
{
|
||||||
/* check whether the to_user exists */
|
if (users[k]->user_id == to_user_id)
|
||||||
struct ConnectedUser *ping_user = NULL;
|
|
||||||
for (size_t k = 0; k < user_count; ++k)
|
|
||||||
{
|
{
|
||||||
if (users[k]->user_id == to_user_id)
|
ping_user = users[k];
|
||||||
{
|
break;
|
||||||
ping_user = users[k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (NULL == ping_user)
|
|
||||||
{
|
|
||||||
chat_addmessage (0,
|
|
||||||
from_user_id,
|
|
||||||
"error||Couldn't find the specified user for pinging.",
|
|
||||||
52,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* if pinging is requested, */
|
|
||||||
/* we mark the user and inform the sender about this */
|
|
||||||
if (0 == ping_user->ping_status)
|
|
||||||
{
|
|
||||||
ping_user->ping_status = 1;
|
|
||||||
pthread_cond_signal (&ping_user->wake_up_sender);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
}
|
}
|
||||||
else
|
if (NULL == ping_user)
|
||||||
{
|
{
|
||||||
chat_addmessage (0,
|
chat_addmessage (0,
|
||||||
from_user_id,
|
from_user_id,
|
||||||
"error||Error while pinging.",
|
"error||Couldn't find the specified user for pinging.",
|
||||||
27,
|
52,
|
||||||
0,
|
0,
|
||||||
1);
|
0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* if pinging is requested, */
|
||||||
|
/* we mark the user and inform the sender about this */
|
||||||
|
if (0 == ping_user->ping_status)
|
||||||
|
{
|
||||||
|
ping_user->ping_status = 1;
|
||||||
|
pthread_cond_signal (&ping_user->wake_up_sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1591,135 +1586,134 @@ connecteduser_send_messages (void *cls)
|
|||||||
struct ConnectedUser *cu = cls;
|
struct ConnectedUser *cu = cls;
|
||||||
|
|
||||||
/* the main loop of sending messages requires to lock the mutex */
|
/* the main loop of sending messages requires to lock the mutex */
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
for (;;)
|
/* loop while not all messages processed */
|
||||||
|
int all_messages_read = 0;
|
||||||
|
while (0 == all_messages_read)
|
||||||
{
|
{
|
||||||
/* loop while not all messages processed */
|
if (1 == disconnect_all)
|
||||||
int all_messages_read = 0;
|
|
||||||
while (0 == all_messages_read)
|
|
||||||
{
|
{
|
||||||
if (1 == disconnect_all)
|
/* the application closes and want that we disconnect all users */
|
||||||
|
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
||||||
|
if (NULL != urh)
|
||||||
{
|
{
|
||||||
/* the application closes and want that we disconnect all users */
|
/* Close the TCP/IP socket. */
|
||||||
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
/* This will also wake-up the waiting receive-thread for this connected user. */
|
||||||
if (NULL != urh)
|
cu->urh = NULL;
|
||||||
{
|
MHD_upgrade_action (urh,
|
||||||
/* Close the TCP/IP socket. */
|
MHD_UPGRADE_ACTION_CLOSE);
|
||||||
/* This will also wake-up the waiting receive-thread for this connected user. */
|
|
||||||
cu->urh = NULL;
|
|
||||||
MHD_upgrade_action (urh,
|
|
||||||
MHD_UPGRADE_ACTION_CLOSE);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
else if (1 == cu->disconnect)
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (1 == cu->disconnect)
|
||||||
|
{
|
||||||
|
/* The sender thread shall close. */
|
||||||
|
/* This is only requested by the receive thread, so we can just leave. */
|
||||||
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (1 == cu->ping_status)
|
||||||
|
{
|
||||||
|
/* A pending ping is requested */
|
||||||
|
++cu->ping_counter;
|
||||||
|
strcpy (cu->ping_message,
|
||||||
|
"libmicrohttpdchatserverpingdata");
|
||||||
|
snprintf (cu->ping_message + 31, 97, "%d", (int) cu->ping_counter);
|
||||||
|
cu->ping_message_len = strlen (cu->ping_message);
|
||||||
|
char *frame_data = NULL;
|
||||||
|
size_t frame_len = 0;
|
||||||
|
int er = MHD_websocket_encode_ping (cu->ws,
|
||||||
|
cu->ping_message,
|
||||||
|
cu->ping_message_len,
|
||||||
|
&frame_data,
|
||||||
|
&frame_len);
|
||||||
|
if (MHD_WEBSOCKET_STATUS_OK == er)
|
||||||
{
|
{
|
||||||
/* The sender thread shall close. */
|
cu->ping_status = 2;
|
||||||
/* This is only requested by the receive thread, so we can just leave. */
|
timespec_get (&cu->ping_start, TIME_UTC);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if (1 == cu->ping_status)
|
|
||||||
{
|
|
||||||
/* A pending ping is requested */
|
|
||||||
++cu->ping_counter;
|
|
||||||
strcpy (cu->ping_message,
|
|
||||||
"libmicrohttpdchatserverpingdata");
|
|
||||||
snprintf (cu->ping_message + 31, 97, "%d", (int) cu->ping_counter);
|
|
||||||
cu->ping_message_len = strlen (cu->ping_message);
|
|
||||||
char *frame_data = NULL;
|
|
||||||
size_t frame_len = 0;
|
|
||||||
int er = MHD_websocket_encode_ping (cu->ws,
|
|
||||||
cu->ping_message,
|
|
||||||
cu->ping_message_len,
|
|
||||||
&frame_data,
|
|
||||||
&frame_len);
|
|
||||||
if (MHD_WEBSOCKET_STATUS_OK == er)
|
|
||||||
{
|
|
||||||
cu->ping_status = 2;
|
|
||||||
timespec_get (&cu->ping_start, TIME_UTC);
|
|
||||||
|
|
||||||
/* send the data via the TCP/IP socket and */
|
/* send the data via the TCP/IP socket and */
|
||||||
/* unlock the mutex while sending */
|
/* unlock the mutex while sending */
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
send_all (cu,
|
abort ();
|
||||||
frame_data,
|
send_all (cu,
|
||||||
frame_len);
|
frame_data,
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
frame_len);
|
||||||
{
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
return NULL;
|
abort ();
|
||||||
}
|
|
||||||
}
|
|
||||||
MHD_websocket_free (cu->ws, frame_data);
|
|
||||||
}
|
}
|
||||||
else if (cu->next_message_index < message_count)
|
MHD_websocket_free (cu->ws, frame_data);
|
||||||
|
}
|
||||||
|
else if (cu->next_message_index < message_count)
|
||||||
|
{
|
||||||
|
/* a chat message or command is pending */
|
||||||
|
char *frame_data = NULL;
|
||||||
|
size_t frame_len = 0;
|
||||||
|
int er = 0;
|
||||||
{
|
{
|
||||||
/* a chat message or command is pending */
|
struct Message *msg = messages[cu->next_message_index];
|
||||||
char *frame_data = NULL;
|
if ((0 == msg->to_user_id) ||
|
||||||
size_t frame_len = 0;
|
(cu->user_id == msg->to_user_id) ||
|
||||||
int er = 0;
|
(cu->user_id == msg->from_user_id) )
|
||||||
{
|
{
|
||||||
struct Message *msg = messages[cu->next_message_index];
|
if (0 == msg->is_binary)
|
||||||
if ((0 == msg->to_user_id) ||
|
|
||||||
(cu->user_id == msg->to_user_id) ||
|
|
||||||
(cu->user_id == msg->from_user_id) )
|
|
||||||
{
|
{
|
||||||
if (0 == msg->is_binary)
|
er = MHD_websocket_encode_text (cu->ws,
|
||||||
{
|
msg->data,
|
||||||
er = MHD_websocket_encode_text (cu->ws,
|
msg->data_len,
|
||||||
|
MHD_WEBSOCKET_FRAGMENTATION_NONE,
|
||||||
|
&frame_data,
|
||||||
|
&frame_len,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
er = MHD_websocket_encode_binary (cu->ws,
|
||||||
msg->data,
|
msg->data,
|
||||||
msg->data_len,
|
msg->data_len,
|
||||||
MHD_WEBSOCKET_FRAGMENTATION_NONE,
|
MHD_WEBSOCKET_FRAGMENTATION_NONE,
|
||||||
&frame_data,
|
&frame_data,
|
||||||
&frame_len,
|
&frame_len);
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
er = MHD_websocket_encode_binary (cu->ws,
|
|
||||||
msg->data,
|
|
||||||
msg->data_len,
|
|
||||||
MHD_WEBSOCKET_FRAGMENTATION_NONE,
|
|
||||||
&frame_data,
|
|
||||||
&frame_len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++cu->next_message_index;
|
|
||||||
|
|
||||||
/* send the data via the TCP/IP socket and */
|
|
||||||
/* unlock the mutex while sending */
|
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
if (MHD_WEBSOCKET_STATUS_OK == er)
|
|
||||||
{
|
|
||||||
send_all (cu,
|
|
||||||
frame_data,
|
|
||||||
frame_len);
|
|
||||||
}
|
|
||||||
MHD_websocket_free (cu->ws,
|
|
||||||
frame_data);
|
|
||||||
if (0 != pthread_mutex_lock (&chat_mutex))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* check whether there are still pending messages */
|
|
||||||
all_messages_read = (cu->next_message_index < message_count) ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
else
|
++cu->next_message_index;
|
||||||
|
|
||||||
|
/* send the data via the TCP/IP socket and */
|
||||||
|
/* unlock the mutex while sending */
|
||||||
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
if (MHD_WEBSOCKET_STATUS_OK == er)
|
||||||
{
|
{
|
||||||
all_messages_read = 1;
|
send_all (cu,
|
||||||
|
frame_data,
|
||||||
|
frame_len);
|
||||||
}
|
}
|
||||||
|
MHD_websocket_free (cu->ws,
|
||||||
|
frame_data);
|
||||||
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
/* check whether there are still pending messages */
|
||||||
|
all_messages_read = (cu->next_message_index < message_count) ? 0 : 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
all_messages_read = 1;
|
||||||
}
|
}
|
||||||
/* clear old messages */
|
|
||||||
chat_clearmessages (0);
|
|
||||||
|
|
||||||
/* Wait for wake up. */
|
|
||||||
/* This will automatically unlock the mutex while waiting and */
|
|
||||||
/* lock the mutex after waiting */
|
|
||||||
pthread_cond_wait (&cu->wake_up_sender, &chat_mutex);
|
|
||||||
}
|
}
|
||||||
|
/* clear old messages */
|
||||||
|
chat_clearmessages (0);
|
||||||
|
|
||||||
|
/* Wait for wake up. */
|
||||||
|
/* This will automatically unlock the mutex while waiting and */
|
||||||
|
/* lock the mutex after waiting */
|
||||||
|
pthread_cond_wait (&cu->wake_up_sender, &chat_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1817,37 +1811,37 @@ connecteduser_receive_messages (void *cls)
|
|||||||
size_t init_users_len = 0;
|
size_t init_users_len = 0;
|
||||||
|
|
||||||
/* first collect all users without sending (so the mutex isn't locked too long) */
|
/* first collect all users without sending (so the mutex isn't locked too long) */
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
if (0 < user_count)
|
||||||
{
|
{
|
||||||
if (0 < user_count)
|
init_users = (struct UserInit *) malloc (user_count * sizeof (struct
|
||||||
|
UserInit));
|
||||||
|
if (NULL != init_users)
|
||||||
{
|
{
|
||||||
init_users = (struct UserInit *) malloc (user_count * sizeof (struct
|
init_users_len = user_count;
|
||||||
UserInit));
|
for (size_t i = 0; i < user_count; ++i)
|
||||||
if (NULL != init_users)
|
|
||||||
{
|
{
|
||||||
init_users_len = user_count;
|
char user_index[32];
|
||||||
for (size_t i = 0; i < user_count; ++i)
|
snprintf (user_index, 32, "%d", (int) users[i]->user_id);
|
||||||
|
size_t user_index_len = strlen (user_index);
|
||||||
|
struct UserInit iu;
|
||||||
|
iu.user_init_len = user_index_len + users[i]->user_name_len + 10;
|
||||||
|
iu.user_init = (char *) malloc (iu.user_init_len + 1);
|
||||||
|
if (NULL != iu.user_init)
|
||||||
{
|
{
|
||||||
char user_index[32];
|
strcpy (iu.user_init, "userinit|");
|
||||||
snprintf (user_index, 32, "%d", (int) users[i]->user_id);
|
strcat (iu.user_init, user_index);
|
||||||
size_t user_index_len = strlen (user_index);
|
strcat (iu.user_init, "|");
|
||||||
struct UserInit iu;
|
if (0 < users[i]->user_name_len)
|
||||||
iu.user_init_len = user_index_len + users[i]->user_name_len + 10;
|
strcat (iu.user_init, users[i]->user_name);
|
||||||
iu.user_init = (char *) malloc (iu.user_init_len + 1);
|
|
||||||
if (NULL != iu.user_init)
|
|
||||||
{
|
|
||||||
strcpy (iu.user_init, "userinit|");
|
|
||||||
strcat (iu.user_init, user_index);
|
|
||||||
strcat (iu.user_init, "|");
|
|
||||||
if (0 < users[i]->user_name_len)
|
|
||||||
strcat (iu.user_init, users[i]->user_name);
|
|
||||||
}
|
|
||||||
init_users[i] = iu;
|
|
||||||
}
|
}
|
||||||
|
init_users[i] = iu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
}
|
}
|
||||||
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
|
||||||
/* then send all users to the connected client */
|
/* then send all users to the connected client */
|
||||||
for (size_t i = 0; i < init_users_len; ++i)
|
for (size_t i = 0; i < init_users_len; ++i)
|
||||||
@@ -1922,13 +1916,14 @@ connecteduser_receive_messages (void *cls)
|
|||||||
cu->extra_in_size))
|
cu->extra_in_size))
|
||||||
{
|
{
|
||||||
chat_removeuser (cu);
|
chat_removeuser (cu);
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
cu->disconnect = 1;
|
cu->disconnect = 1;
|
||||||
pthread_cond_signal (&cu->wake_up_sender);
|
pthread_cond_signal (&cu->wake_up_sender);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
pthread_join (pt, NULL);
|
abort ();
|
||||||
}
|
pthread_join (pt, NULL);
|
||||||
|
|
||||||
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
||||||
if (NULL != urh)
|
if (NULL != urh)
|
||||||
{
|
{
|
||||||
@@ -1967,13 +1962,13 @@ connecteduser_receive_messages (void *cls)
|
|||||||
{
|
{
|
||||||
/* A websocket protocol error occurred */
|
/* A websocket protocol error occurred */
|
||||||
chat_removeuser (cu);
|
chat_removeuser (cu);
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
cu->disconnect = 1;
|
cu->disconnect = 1;
|
||||||
pthread_cond_signal (&cu->wake_up_sender);
|
pthread_cond_signal (&cu->wake_up_sender);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
pthread_join (pt, NULL);
|
abort ();
|
||||||
}
|
pthread_join (pt, NULL);
|
||||||
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
||||||
if (NULL != urh)
|
if (NULL != urh)
|
||||||
{
|
{
|
||||||
@@ -1993,13 +1988,13 @@ connecteduser_receive_messages (void *cls)
|
|||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
chat_removeuser (cu);
|
chat_removeuser (cu);
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
cu->disconnect = 1;
|
cu->disconnect = 1;
|
||||||
pthread_cond_signal (&cu->wake_up_sender);
|
pthread_cond_signal (&cu->wake_up_sender);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
pthread_join (pt, NULL);
|
abort ();
|
||||||
}
|
pthread_join (pt, NULL);
|
||||||
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
struct MHD_UpgradeResponseHandle *urh = cu->urh;
|
||||||
if (NULL != urh)
|
if (NULL != urh)
|
||||||
{
|
{
|
||||||
@@ -2322,28 +2317,28 @@ main (int argc,
|
|||||||
return 1;
|
return 1;
|
||||||
(void) getc (stdin);
|
(void) getc (stdin);
|
||||||
|
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
{
|
abort ();
|
||||||
disconnect_all = 1;
|
disconnect_all = 1;
|
||||||
for (size_t i = 0; i < user_count; ++i)
|
for (size_t i = 0; i < user_count; ++i)
|
||||||
pthread_cond_signal (&users[i]->wake_up_sender);
|
pthread_cond_signal (&users[i]->wake_up_sender);
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
}
|
abort ();
|
||||||
sleep (2);
|
sleep (2);
|
||||||
if (0 == pthread_mutex_lock (&chat_mutex))
|
if (0 != pthread_mutex_lock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
|
for (size_t i = 0; i < user_count; ++i)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < user_count; ++i)
|
struct MHD_UpgradeResponseHandle *urh = users[i]->urh;
|
||||||
|
if (NULL != urh)
|
||||||
{
|
{
|
||||||
struct MHD_UpgradeResponseHandle *urh = users[i]->urh;
|
users[i]->urh = NULL;
|
||||||
if (NULL != urh)
|
MHD_upgrade_action (users[i]->urh,
|
||||||
{
|
MHD_UPGRADE_ACTION_CLOSE);
|
||||||
users[i]->urh = NULL;
|
|
||||||
MHD_upgrade_action (users[i]->urh,
|
|
||||||
MHD_UPGRADE_ACTION_CLOSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&chat_mutex);
|
|
||||||
}
|
}
|
||||||
|
if (0 != pthread_mutex_unlock (&chat_mutex))
|
||||||
|
abort ();
|
||||||
sleep (2);
|
sleep (2);
|
||||||
|
|
||||||
/* usually we should wait here in a safe way for all threads to disconnect, */
|
/* usually we should wait here in a safe way for all threads to disconnect, */
|
||||||
|
|||||||
@@ -625,7 +625,8 @@ ws_send_frame (MHD_socket sock, const char *msg, size_t length)
|
|||||||
}
|
}
|
||||||
response[idx_response] = '\0';
|
response[idx_response] = '\0';
|
||||||
output = 0;
|
output = 0;
|
||||||
pthread_mutex_lock (&MUTEX);
|
if (0 != pthread_mutex_lock (&MUTEX))
|
||||||
|
abort ();
|
||||||
for (i = 0; i < MAX_CLIENTS; i++)
|
for (i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
isock = CLIENT_SOCKS[i];
|
isock = CLIENT_SOCKS[i];
|
||||||
@@ -634,7 +635,8 @@ ws_send_frame (MHD_socket sock, const char *msg, size_t length)
|
|||||||
output += send_all (isock, response, idx_response);
|
output += send_all (isock, response, idx_response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&MUTEX);
|
if (0 != pthread_mutex_unlock (&MUTEX))
|
||||||
|
abort ();
|
||||||
free (response);
|
free (response);
|
||||||
return (ssize_t) output;
|
return (ssize_t) output;
|
||||||
}
|
}
|
||||||
@@ -759,7 +761,8 @@ run_usock (void *cls)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_lock (&MUTEX);
|
if (0 != pthread_mutex_lock (&MUTEX))
|
||||||
|
abort ();
|
||||||
for (i = 0; i < MAX_CLIENTS; i++)
|
for (i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if (CLIENT_SOCKS[i] == ws->sock)
|
if (CLIENT_SOCKS[i] == ws->sock)
|
||||||
@@ -768,7 +771,8 @@ run_usock (void *cls)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&MUTEX);
|
if (0 != pthread_mutex_unlock (&MUTEX))
|
||||||
|
abort ();
|
||||||
free (ws);
|
free (ws);
|
||||||
MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE);
|
MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -798,7 +802,8 @@ uh_cb (void *cls, struct MHD_Connection *con, void *req_cls,
|
|||||||
ws->sock = sock;
|
ws->sock = sock;
|
||||||
ws->urh = urh;
|
ws->urh = urh;
|
||||||
sock_overflow = MHD_YES;
|
sock_overflow = MHD_YES;
|
||||||
pthread_mutex_lock (&MUTEX);
|
if (0 != pthread_mutex_lock (&MUTEX))
|
||||||
|
abort ();
|
||||||
for (i = 0; i < MAX_CLIENTS; i++)
|
for (i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if (MHD_INVALID_SOCKET == CLIENT_SOCKS[i])
|
if (MHD_INVALID_SOCKET == CLIENT_SOCKS[i])
|
||||||
@@ -808,7 +813,8 @@ uh_cb (void *cls, struct MHD_Connection *con, void *req_cls,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&MUTEX);
|
if (0 != pthread_mutex_unlock (&MUTEX))
|
||||||
|
abort ();
|
||||||
if (sock_overflow)
|
if (sock_overflow)
|
||||||
{
|
{
|
||||||
free (ws);
|
free (ws);
|
||||||
|
|||||||
Reference in New Issue
Block a user