aboutsummaryrefslogtreecommitdiff
path: root/src/examples/websocket_chatserver_example.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/websocket_chatserver_example.c')
-rw-r--r--src/examples/websocket_chatserver_example.c481
1 files changed, 238 insertions, 243 deletions
diff --git a/src/examples/websocket_chatserver_example.c b/src/examples/websocket_chatserver_example.c
index f4aac7b3..9e5319ad 100644
--- a/src/examples/websocket_chatserver_example.c
+++ b/src/examples/websocket_chatserver_example.c
@@ -187,8 +187,9 @@
187 " function window_onload(event)\n" \ 187 " function window_onload(event)\n" \
188 " {\n" \ 188 " {\n" \
189 " /* Determine the base url (for http:/" "/ this is ws:/" "/ for https:/" \ 189 " /* Determine the base url (for http:/" "/ this is ws:/" "/ for https:/" \
190 "/ this must be wss:/" "/) */\n" \ 190 "/ this must be wss:/" "/) */\n" \
191 " baseUrl = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + ':/" "/' + window.location.host + '/ChatServerWebSocket';\n" \ 191 " baseUrl = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + ':/" \
192 "/' + window.location.host + '/ChatServerWebSocket';\n" \
192 " chat_generate();\n" \ 193 " chat_generate();\n" \
193 " chat_connect();\n" \ 194 " chat_connect();\n" \
194 " }\n" \ 195 " }\n" \
@@ -586,7 +587,7 @@
586 " let message = [ ];\n" \ 587 " let message = [ ];\n" \
587 " /* message type */ \n" \ 588 " /* message type */ \n" \
588 " let j = 0;\n" \ 589 " let j = 0;\n" \
589 " let i = byteData.indexOf(0x7C, j); /* | = 0x7C;*/ \n"\ 590 " let i = byteData.indexOf(0x7C, j); /* | = 0x7C;*/ \n" \
590 " if(i < 0)\n" \ 591 " if(i < 0)\n" \
591 " return;\n" \ 592 " return;\n" \
592 " message.push(decoder.decode(byteData.slice(0, i)));\n" \ 593 " message.push(decoder.decode(byteData.slice(0, i)));\n" \
@@ -737,28 +738,28 @@ send_all (struct ConnectedUser *cu,
737 ssize_t ret; 738 ssize_t ret;
738 size_t off; 739 size_t off;
739 740
740 if (0 == pthread_mutex_lock (&cu->send_mutex)) 741 if (0 != pthread_mutex_lock (&cu->send_mutex))
742 abort ();
743 for (off = 0; off < len; off += ret)
741 { 744 {
742 for (off = 0; off < len; off += ret) 745 ret = send (cu->fd,
746 &buf[off],
747 (int) (len - off),
748 0);
749 if (0 > ret)
743 { 750 {
744 ret = send (cu->fd, 751 if (EAGAIN == errno)
745 &buf[off],
746 (int) (len - off),
747 0);
748 if (0 > ret)
749 { 752 {
750 if (EAGAIN == errno) 753 ret = 0;
751 { 754 continue;
752 ret = 0;
753 continue;
754 }
755 break;
756 } 755 }
757 if (0 == ret) 756 break;
758 break;
759 } 757 }
760 pthread_mutex_unlock (&cu->send_mutex); 758 if (0 == ret)
759 break;
761 } 760 }
761 if (0 != pthread_mutex_unlock (&cu->send_mutex))
762 abort ();
762} 763}
763 764
764 765
@@ -806,7 +807,7 @@ chat_addmessage (size_t from_user_id,
806 if (0 != needs_lock) 807 if (0 != needs_lock)
807 { 808 {
808 if (0 != pthread_mutex_lock (&chat_mutex)) 809 if (0 != pthread_mutex_lock (&chat_mutex))
809 return 1; 810 abort ();
810 } 811 }
811 812
812 /* add the new message to the global message list */ 813 /* add the new message to the global message list */
@@ -819,7 +820,8 @@ chat_addmessage (size_t from_user_id,
819 { 820 {
820 free (message); 821 free (message);
821 if (0 != needs_lock) 822 if (0 != needs_lock)
822 pthread_mutex_unlock (&chat_mutex); 823 if (0 != pthread_mutex_unlock (&chat_mutex))
824 abort ();
823 return 1; 825 return 1;
824 } 826 }
825 messages_[message_count] = message; 827 messages_[message_count] = message;
@@ -834,7 +836,8 @@ chat_addmessage (size_t from_user_id,
834 if (0 != needs_lock) 836 if (0 != needs_lock)
835 { 837 {
836 if (0 != needs_lock) 838 if (0 != needs_lock)
837 pthread_mutex_unlock (&chat_mutex); 839 if (0 != pthread_mutex_unlock (&chat_mutex))
840 abort ();
838 } 841 }
839 return 0; 842 return 0;
840} 843}
@@ -854,7 +857,7 @@ chat_clearmessages (int needs_lock)
854 if (0 != needs_lock) 857 if (0 != needs_lock)
855 { 858 {
856 if (0 != pthread_mutex_lock (&chat_mutex)) 859 if (0 != pthread_mutex_lock (&chat_mutex))
857 return 1; 860 abort ();
858 } 861 }
859 862
860 /* update the clean counter and check whether we need cleaning */ 863 /* update the clean counter and check whether we need cleaning */
@@ -864,7 +867,8 @@ chat_clearmessages (int needs_lock)
864 /* no cleanup required */ 867 /* no cleanup required */
865 if (0 != needs_lock) 868 if (0 != needs_lock)
866 { 869 {
867 pthread_mutex_unlock (&chat_mutex); 870 if (0 != pthread_mutex_unlock (&chat_mutex))
871 abort ();
868 } 872 }
869 return 0; 873 return 0;
870 } 874 }
@@ -916,7 +920,8 @@ chat_clearmessages (int needs_lock)
916 /* unlock the global mutex if needed */ 920 /* unlock the global mutex if needed */
917 if (0 != needs_lock) 921 if (0 != needs_lock)
918 { 922 {
919 pthread_mutex_unlock (&chat_mutex); 923 if (0 != pthread_mutex_unlock (&chat_mutex))
924 abort ();
920 } 925 }
921 return 0; 926 return 0;
922} 927}
@@ -947,10 +952,7 @@ chat_adduser (struct ConnectedUser *cu)
947 952
948 /* lock the mutex */ 953 /* lock the mutex */
949 if (0 != pthread_mutex_lock (&chat_mutex)) 954 if (0 != pthread_mutex_lock (&chat_mutex))
950 { 955 abort ();
951 free (data);
952 return 1;
953 }
954 /* inform the other chat users about the new user */ 956 /* inform the other chat users about the new user */
955 if (0 != chat_addmessage (0, 957 if (0 != chat_addmessage (0,
956 0, 958 0,
@@ -960,7 +962,8 @@ chat_adduser (struct ConnectedUser *cu)
960 0)) 962 0))
961 { 963 {
962 free (data); 964 free (data);
963 pthread_mutex_unlock (&chat_mutex); 965 if (0 != pthread_mutex_unlock (&chat_mutex))
966 abort ();
964 return 1; 967 return 1;
965 } 968 }
966 free (data); 969 free (data);
@@ -973,7 +976,8 @@ chat_adduser (struct ConnectedUser *cu)
973 if (NULL == users_) 976 if (NULL == users_)
974 { 977 {
975 /* realloc failed */ 978 /* realloc failed */
976 pthread_mutex_unlock (&chat_mutex); 979 if (0 != pthread_mutex_unlock (&chat_mutex))
980 abort ();
977 return 1; 981 return 1;
978 } 982 }
979 users_[user_count] = cu; 983 users_[user_count] = cu;
@@ -985,7 +989,8 @@ chat_adduser (struct ConnectedUser *cu)
985 cu->next_message_index = message_count; 989 cu->next_message_index = message_count;
986 990
987 /* unlock the mutex */ 991 /* unlock the mutex */
988 pthread_mutex_unlock (&chat_mutex); 992 if (0 != pthread_mutex_unlock (&chat_mutex))
993 abort ();
989 return 0; 994 return 0;
990} 995}
991 996
@@ -1014,10 +1019,7 @@ chat_removeuser (struct ConnectedUser *cu)
1014 1019
1015 /* lock the mutex */ 1020 /* lock the mutex */
1016 if (0 != pthread_mutex_lock (&chat_mutex)) 1021 if (0 != pthread_mutex_lock (&chat_mutex))
1017 { 1022 abort ();
1018 free (data);
1019 return 1;
1020 }
1021 /* inform the other chat users that the user is gone */ 1023 /* inform the other chat users that the user is gone */
1022 int got_error = 0; 1024 int got_error = 0;
1023 if (0 != chat_addmessage (0, 0, data, data_len, 0, 0)) 1025 if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
@@ -1045,7 +1047,8 @@ chat_removeuser (struct ConnectedUser *cu)
1045 got_error = 1; 1047 got_error = 1;
1046 1048
1047 /* unlock the mutex */ 1049 /* unlock the mutex */
1048 pthread_mutex_unlock (&chat_mutex); 1050 if (0 != pthread_mutex_unlock (&chat_mutex))
1051 abort ();
1049 1052
1050 return got_error; 1053 return got_error;
1051} 1054}
@@ -1066,9 +1069,7 @@ chat_renameuser (struct ConnectedUser *cu,
1066{ 1069{
1067 /* lock the mutex */ 1070 /* lock the mutex */
1068 if (0 != pthread_mutex_lock (&chat_mutex)) 1071 if (0 != pthread_mutex_lock (&chat_mutex))
1069 { 1072 abort ();
1070 return 1;
1071 }
1072 1073
1073 /* check whether the name is already in use */ 1074 /* check whether the name is already in use */
1074 for (size_t i = 0; i < user_count; ++i) 1075 for (size_t i = 0; i < user_count; ++i)
@@ -1078,7 +1079,8 @@ chat_renameuser (struct ConnectedUser *cu,
1078 if ((users[i]->user_name_len == new_name_len) && 1079 if ((users[i]->user_name_len == new_name_len) &&
1079 (0 == strcasecmp (users[i]->user_name, new_name))) 1080 (0 == strcasecmp (users[i]->user_name, new_name)))
1080 { 1081 {
1081 pthread_mutex_unlock (&chat_mutex); 1082 if (0 != pthread_mutex_unlock (&chat_mutex))
1083 abort ();
1082 return 2; 1084 return 2;
1083 } 1085 }
1084 } 1086 }
@@ -1101,7 +1103,8 @@ chat_renameuser (struct ConnectedUser *cu,
1101 if (0 != chat_addmessage (0, 0, data, data_len, 0, 0)) 1103 if (0 != chat_addmessage (0, 0, data, data_len, 0, 0))
1102 { 1104 {
1103 free (data); 1105 free (data);
1104 pthread_mutex_unlock (&chat_mutex); 1106 if (0 != pthread_mutex_unlock (&chat_mutex))
1107 abort ();
1105 return 1; 1108 return 1;
1106 } 1109 }
1107 free (data); 1110 free (data);
@@ -1112,7 +1115,8 @@ chat_renameuser (struct ConnectedUser *cu,
1112 cu->user_name_len = new_name_len; 1115 cu->user_name_len = new_name_len;
1113 1116
1114 /* unlock the mutex */ 1117 /* unlock the mutex */
1115 pthread_mutex_unlock (&chat_mutex); 1118 if (0 != pthread_mutex_unlock (&chat_mutex))
1119 abort ();
1116 1120
1117 return 0; 1121 return 0;
1118} 1122}
@@ -1411,48 +1415,39 @@ connecteduser_parse_received_websocket_stream (struct ConnectedUser *cu,
1411 case 3: 1415 case 3:
1412 /* ping */ 1416 /* ping */
1413 { 1417 {
1414 if (0 == pthread_mutex_lock (&chat_mutex)) 1418 if (0 != pthread_mutex_lock (&chat_mutex))
1419 abort ();
1420 /* check whether the to_user exists */
1421 struct ConnectedUser *ping_user = NULL;
1422 for (size_t k = 0; k < user_count; ++k)
1415 { 1423 {
1416 /* check whether the to_user exists */ 1424 if (users[k]->user_id == to_user_id)
1417 struct ConnectedUser *ping_user = NULL;
1418 for (size_t k = 0; k < user_count; ++k)
1419 {
1420 if (users[k]->user_id == to_user_id)
1421 {
1422 ping_user = users[k];
1423 break;
1424 }
1425 }
1426 if (NULL == ping_user)
1427 {
1428 chat_addmessage (0,
1429 from_user_id,
1430 "error||Couldn't find the specified user for pinging.",
1431 52,
1432 0,
1433 0);
1434 }
1435 else
1436 { 1425 {
1437 /* if pinging is requested, */ 1426 ping_user = users[k];
1438 /* we mark the user and inform the sender about this */ 1427 break;
1439 if (0 == ping_user->ping_status)
1440 {
1441 ping_user->ping_status = 1;
1442 pthread_cond_signal (&ping_user->wake_up_sender);
1443 }
1444 } 1428 }
1445 pthread_mutex_unlock (&chat_mutex);
1446 } 1429 }
1447 else 1430 if (NULL == ping_user)
1448 { 1431 {
1449 chat_addmessage (0, 1432 chat_addmessage (0,
1450 from_user_id, 1433 from_user_id,
1451 "error||Error while pinging.", 1434 "error||Couldn't find the specified user for pinging.",
1452 27, 1435 52,
1453 0, 1436 0,
1454 1); 1437 0);
1438 }
1439 else
1440 {
1441 /* if pinging is requested, */
1442 /* we mark the user and inform the sender about this */
1443 if (0 == ping_user->ping_status)
1444 {
1445 ping_user->ping_status = 1;
1446 pthread_cond_signal (&ping_user->wake_up_sender);
1447 }
1455 } 1448 }
1449 if (0 != pthread_mutex_unlock (&chat_mutex))
1450 abort ();
1456 } 1451 }
1457 break; 1452 break;
1458 1453
@@ -1591,135 +1586,134 @@ connecteduser_send_messages (void *cls)
1591 struct ConnectedUser *cu = cls; 1586 struct ConnectedUser *cu = cls;
1592 1587
1593 /* the main loop of sending messages requires to lock the mutex */ 1588 /* the main loop of sending messages requires to lock the mutex */
1594 if (0 == pthread_mutex_lock (&chat_mutex)) 1589 if (0 != pthread_mutex_lock (&chat_mutex))
1590 abort ();
1591 for (;;)
1595 { 1592 {
1596 for (;;) 1593 /* loop while not all messages processed */
1594 int all_messages_read = 0;
1595 while (0 == all_messages_read)
1597 { 1596 {
1598 /* loop while not all messages processed */ 1597 if (1 == disconnect_all)
1599 int all_messages_read = 0;
1600 while (0 == all_messages_read)
1601 { 1598 {
1602 if (1 == disconnect_all) 1599 /* the application closes and want that we disconnect all users */
1600 struct MHD_UpgradeResponseHandle *urh = cu->urh;
1601 if (NULL != urh)
1603 { 1602 {
1604 /* the application closes and want that we disconnect all users */ 1603 /* Close the TCP/IP socket. */
1605 struct MHD_UpgradeResponseHandle *urh = cu->urh; 1604 /* This will also wake-up the waiting receive-thread for this connected user. */
1606 if (NULL != urh) 1605 cu->urh = NULL;
1607 { 1606 MHD_upgrade_action (urh,
1608 /* Close the TCP/IP socket. */ 1607 MHD_UPGRADE_ACTION_CLOSE);
1609 /* This will also wake-up the waiting receive-thread for this connected user. */
1610 cu->urh = NULL;
1611 MHD_upgrade_action (urh,
1612 MHD_UPGRADE_ACTION_CLOSE);
1613 }
1614 pthread_mutex_unlock (&chat_mutex);
1615 return NULL;
1616 } 1608 }
1617 else if (1 == cu->disconnect) 1609 if (0 != pthread_mutex_unlock (&chat_mutex))
1610 abort ();
1611 return NULL;
1612 }
1613 else if (1 == cu->disconnect)
1614 {
1615 /* The sender thread shall close. */
1616 /* This is only requested by the receive thread, so we can just leave. */
1617 if (0 != pthread_mutex_unlock (&chat_mutex))
1618 abort ();
1619 return NULL;
1620 }
1621 else if (1 == cu->ping_status)
1622 {
1623 /* A pending ping is requested */
1624 ++cu->ping_counter;
1625 strcpy (cu->ping_message,
1626 "libmicrohttpdchatserverpingdata");
1627 snprintf (cu->ping_message + 31, 97, "%d", (int) cu->ping_counter);
1628 cu->ping_message_len = strlen (cu->ping_message);
1629 char *frame_data = NULL;
1630 size_t frame_len = 0;
1631 int er = MHD_websocket_encode_ping (cu->ws,
1632 cu->ping_message,
1633 cu->ping_message_len,
1634 &frame_data,
1635 &frame_len);
1636 if (MHD_WEBSOCKET_STATUS_OK == er)
1618 { 1637 {
1619 /* The sender thread shall close. */ 1638 cu->ping_status = 2;
1620 /* This is only requested by the receive thread, so we can just leave. */ 1639 timespec_get (&cu->ping_start, TIME_UTC);
1621 pthread_mutex_unlock (&chat_mutex); 1640
1622 return NULL; 1641 /* send the data via the TCP/IP socket and */
1642 /* unlock the mutex while sending */
1643 if (0 != pthread_mutex_unlock (&chat_mutex))
1644 abort ();
1645 send_all (cu,
1646 frame_data,
1647 frame_len);
1648 if (0 != pthread_mutex_lock (&chat_mutex))
1649 abort ();
1623 } 1650 }
1624 else if (1 == cu->ping_status) 1651 MHD_websocket_free (cu->ws, frame_data);
1652 }
1653 else if (cu->next_message_index < message_count)
1654 {
1655 /* a chat message or command is pending */
1656 char *frame_data = NULL;
1657 size_t frame_len = 0;
1658 int er = 0;
1625 { 1659 {
1626 /* A pending ping is requested */ 1660 struct Message *msg = messages[cu->next_message_index];
1627 ++cu->ping_counter; 1661 if ((0 == msg->to_user_id) ||
1628 strcpy (cu->ping_message, 1662 (cu->user_id == msg->to_user_id) ||
1629 "libmicrohttpdchatserverpingdata"); 1663 (cu->user_id == msg->from_user_id) )
1630 snprintf (cu->ping_message + 31, 97, "%d", (int) cu->ping_counter);
1631 cu->ping_message_len = strlen (cu->ping_message);
1632 char *frame_data = NULL;
1633 size_t frame_len = 0;
1634 int er = MHD_websocket_encode_ping (cu->ws,
1635 cu->ping_message,
1636 cu->ping_message_len,
1637 &frame_data,
1638 &frame_len);
1639 if (MHD_WEBSOCKET_STATUS_OK == er)
1640 { 1664 {
1641 cu->ping_status = 2; 1665 if (0 == msg->is_binary)
1642 timespec_get (&cu->ping_start, TIME_UTC);
1643
1644 /* send the data via the TCP/IP socket and */
1645 /* unlock the mutex while sending */
1646 pthread_mutex_unlock (&chat_mutex);
1647 send_all (cu,
1648 frame_data,
1649 frame_len);
1650 if (0 != pthread_mutex_lock (&chat_mutex))
1651 { 1666 {
1652 return NULL; 1667 er = MHD_websocket_encode_text (cu->ws,
1668 msg->data,
1669 msg->data_len,
1670 MHD_WEBSOCKET_FRAGMENTATION_NONE,
1671 &frame_data,
1672 &frame_len,
1673 NULL);
1653 } 1674 }
1654 } 1675 else
1655 MHD_websocket_free (cu->ws, frame_data);
1656 }
1657 else if (cu->next_message_index < message_count)
1658 {
1659 /* a chat message or command is pending */
1660 char *frame_data = NULL;
1661 size_t frame_len = 0;
1662 int er = 0;
1663 {
1664 struct Message *msg = messages[cu->next_message_index];
1665 if ((0 == msg->to_user_id) ||
1666 (cu->user_id == msg->to_user_id) ||
1667 (cu->user_id == msg->from_user_id) )
1668 { 1676 {
1669 if (0 == msg->is_binary) 1677 er = MHD_websocket_encode_binary (cu->ws,
1670 {
1671 er = MHD_websocket_encode_text (cu->ws,
1672 msg->data, 1678 msg->data,
1673 msg->data_len, 1679 msg->data_len,
1674 MHD_WEBSOCKET_FRAGMENTATION_NONE, 1680 MHD_WEBSOCKET_FRAGMENTATION_NONE,
1675 &frame_data, 1681 &frame_data,
1676 &frame_len, 1682 &frame_len);
1677 NULL);
1678 }
1679 else
1680 {
1681 er = MHD_websocket_encode_binary (cu->ws,
1682 msg->data,
1683 msg->data_len,
1684 MHD_WEBSOCKET_FRAGMENTATION_NONE,
1685 &frame_data,
1686 &frame_len);
1687 }
1688 } 1683 }
1689 } 1684 }
1690 ++cu->next_message_index;
1691
1692 /* send the data via the TCP/IP socket and */
1693 /* unlock the mutex while sending */
1694 pthread_mutex_unlock (&chat_mutex);
1695 if (MHD_WEBSOCKET_STATUS_OK == er)
1696 {
1697 send_all (cu,
1698 frame_data,
1699 frame_len);
1700 }
1701 MHD_websocket_free (cu->ws,
1702 frame_data);
1703 if (0 != pthread_mutex_lock (&chat_mutex))
1704 {
1705 return NULL;
1706 }
1707 /* check whether there are still pending messages */
1708 all_messages_read = (cu->next_message_index < message_count) ? 0 : 1;
1709 } 1685 }
1710 else 1686 ++cu->next_message_index;
1687
1688 /* send the data via the TCP/IP socket and */
1689 /* unlock the mutex while sending */
1690 if (0 != pthread_mutex_unlock (&chat_mutex))
1691 abort ();
1692 if (MHD_WEBSOCKET_STATUS_OK == er)
1711 { 1693 {
1712 all_messages_read = 1; 1694 send_all (cu,
1695 frame_data,
1696 frame_len);
1713 } 1697 }
1698 MHD_websocket_free (cu->ws,
1699 frame_data);
1700 if (0 != pthread_mutex_lock (&chat_mutex))
1701 abort ();
1702 /* check whether there are still pending messages */
1703 all_messages_read = (cu->next_message_index < message_count) ? 0 : 1;
1704 }
1705 else
1706 {
1707 all_messages_read = 1;
1714 } 1708 }
1715 /* clear old messages */
1716 chat_clearmessages (0);
1717
1718 /* Wait for wake up. */
1719 /* This will automatically unlock the mutex while waiting and */
1720 /* lock the mutex after waiting */
1721 pthread_cond_wait (&cu->wake_up_sender, &chat_mutex);
1722 } 1709 }
1710 /* clear old messages */
1711 chat_clearmessages (0);
1712
1713 /* Wait for wake up. */
1714 /* This will automatically unlock the mutex while waiting and */
1715 /* lock the mutex after waiting */
1716 pthread_cond_wait (&cu->wake_up_sender, &chat_mutex);
1723 } 1717 }
1724 1718
1725 return NULL; 1719 return NULL;
@@ -1817,37 +1811,37 @@ connecteduser_receive_messages (void *cls)
1817 size_t init_users_len = 0; 1811 size_t init_users_len = 0;
1818 1812
1819 /* first collect all users without sending (so the mutex isn't locked too long) */ 1813 /* first collect all users without sending (so the mutex isn't locked too long) */
1820 if (0 == pthread_mutex_lock (&chat_mutex)) 1814 if (0 != pthread_mutex_lock (&chat_mutex))
1815 abort ();
1816 if (0 < user_count)
1821 { 1817 {
1822 if (0 < user_count) 1818 init_users = (struct UserInit *) malloc (user_count * sizeof (struct
1819 UserInit));
1820 if (NULL != init_users)
1823 { 1821 {
1824 init_users = (struct UserInit *) malloc (user_count * sizeof (struct 1822 init_users_len = user_count;
1825 UserInit)); 1823 for (size_t i = 0; i < user_count; ++i)
1826 if (NULL != init_users)
1827 { 1824 {
1828 init_users_len = user_count; 1825 char user_index[32];
1829 for (size_t i = 0; i < user_count; ++i) 1826 snprintf (user_index, 32, "%d", (int) users[i]->user_id);
1827 size_t user_index_len = strlen (user_index);
1828 struct UserInit iu;
1829 iu.user_init_len = user_index_len + users[i]->user_name_len + 10;
1830 iu.user_init = (char *) malloc (iu.user_init_len + 1);
1831 if (NULL != iu.user_init)
1830 { 1832 {
1831 char user_index[32]; 1833 strcpy (iu.user_init, "userinit|");
1832 snprintf (user_index, 32, "%d", (int) users[i]->user_id); 1834 strcat (iu.user_init, user_index);
1833 size_t user_index_len = strlen (user_index); 1835 strcat (iu.user_init, "|");
1834 struct UserInit iu; 1836 if (0 < users[i]->user_name_len)
1835 iu.user_init_len = user_index_len + users[i]->user_name_len + 10; 1837 strcat (iu.user_init, users[i]->user_name);
1836 iu.user_init = (char *) malloc (iu.user_init_len + 1);
1837 if (NULL != iu.user_init)
1838 {
1839 strcpy (iu.user_init, "userinit|");
1840 strcat (iu.user_init, user_index);
1841 strcat (iu.user_init, "|");
1842 if (0 < users[i]->user_name_len)
1843 strcat (iu.user_init, users[i]->user_name);
1844 }
1845 init_users[i] = iu;
1846 } 1838 }
1839 init_users[i] = iu;
1847 } 1840 }
1848 } 1841 }
1849 pthread_mutex_unlock (&chat_mutex);
1850 } 1842 }
1843 if (0 != pthread_mutex_unlock (&chat_mutex))
1844 abort ();
1851 1845
1852 /* then send all users to the connected client */ 1846 /* then send all users to the connected client */
1853 for (size_t i = 0; i < init_users_len; ++i) 1847 for (size_t i = 0; i < init_users_len; ++i)
@@ -1922,13 +1916,14 @@ connecteduser_receive_messages (void *cls)
1922 cu->extra_in_size)) 1916 cu->extra_in_size))
1923 { 1917 {
1924 chat_removeuser (cu); 1918 chat_removeuser (cu);
1925 if (0 == pthread_mutex_lock (&chat_mutex)) 1919 if (0 != pthread_mutex_lock (&chat_mutex))
1926 { 1920 abort ();
1927 cu->disconnect = 1; 1921 cu->disconnect = 1;
1928 pthread_cond_signal (&cu->wake_up_sender); 1922 pthread_cond_signal (&cu->wake_up_sender);
1929 pthread_mutex_unlock (&chat_mutex); 1923 if (0 != pthread_mutex_unlock (&chat_mutex))
1930 pthread_join (pt, NULL); 1924 abort ();
1931 } 1925 pthread_join (pt, NULL);
1926
1932 struct MHD_UpgradeResponseHandle *urh = cu->urh; 1927 struct MHD_UpgradeResponseHandle *urh = cu->urh;
1933 if (NULL != urh) 1928 if (NULL != urh)
1934 { 1929 {
@@ -1967,13 +1962,13 @@ connecteduser_receive_messages (void *cls)
1967 { 1962 {
1968 /* A websocket protocol error occurred */ 1963 /* A websocket protocol error occurred */
1969 chat_removeuser (cu); 1964 chat_removeuser (cu);
1970 if (0 == pthread_mutex_lock (&chat_mutex)) 1965 if (0 != pthread_mutex_lock (&chat_mutex))
1971 { 1966 abort ();
1972 cu->disconnect = 1; 1967 cu->disconnect = 1;
1973 pthread_cond_signal (&cu->wake_up_sender); 1968 pthread_cond_signal (&cu->wake_up_sender);
1974 pthread_mutex_unlock (&chat_mutex); 1969 if (0 != pthread_mutex_unlock (&chat_mutex))
1975 pthread_join (pt, NULL); 1970 abort ();
1976 } 1971 pthread_join (pt, NULL);
1977 struct MHD_UpgradeResponseHandle *urh = cu->urh; 1972 struct MHD_UpgradeResponseHandle *urh = cu->urh;
1978 if (NULL != urh) 1973 if (NULL != urh)
1979 { 1974 {
@@ -1993,13 +1988,13 @@ connecteduser_receive_messages (void *cls)
1993 1988
1994 /* cleanup */ 1989 /* cleanup */
1995 chat_removeuser (cu); 1990 chat_removeuser (cu);
1996 if (0 == pthread_mutex_lock (&chat_mutex)) 1991 if (0 != pthread_mutex_lock (&chat_mutex))
1997 { 1992 abort ();
1998 cu->disconnect = 1; 1993 cu->disconnect = 1;
1999 pthread_cond_signal (&cu->wake_up_sender); 1994 pthread_cond_signal (&cu->wake_up_sender);
2000 pthread_mutex_unlock (&chat_mutex); 1995 if (0 != pthread_mutex_unlock (&chat_mutex))
2001 pthread_join (pt, NULL); 1996 abort ();
2002 } 1997 pthread_join (pt, NULL);
2003 struct MHD_UpgradeResponseHandle *urh = cu->urh; 1998 struct MHD_UpgradeResponseHandle *urh = cu->urh;
2004 if (NULL != urh) 1999 if (NULL != urh)
2005 { 2000 {
@@ -2322,28 +2317,28 @@ main (int argc,
2322 return 1; 2317 return 1;
2323 (void) getc (stdin); 2318 (void) getc (stdin);
2324 2319
2325 if (0 == pthread_mutex_lock (&chat_mutex)) 2320 if (0 != pthread_mutex_lock (&chat_mutex))
2326 { 2321 abort ();
2327 disconnect_all = 1; 2322 disconnect_all = 1;
2328 for (size_t i = 0; i < user_count; ++i) 2323 for (size_t i = 0; i < user_count; ++i)
2329 pthread_cond_signal (&users[i]->wake_up_sender); 2324 pthread_cond_signal (&users[i]->wake_up_sender);
2330 pthread_mutex_unlock (&chat_mutex); 2325 if (0 != pthread_mutex_unlock (&chat_mutex))
2331 } 2326 abort ();
2332 sleep (2); 2327 sleep (2);
2333 if (0 == pthread_mutex_lock (&chat_mutex)) 2328 if (0 != pthread_mutex_lock (&chat_mutex))
2329 abort ();
2330 for (size_t i = 0; i < user_count; ++i)
2334 { 2331 {
2335 for (size_t i = 0; i < user_count; ++i) 2332 struct MHD_UpgradeResponseHandle *urh = users[i]->urh;
2333 if (NULL != urh)
2336 { 2334 {
2337 struct MHD_UpgradeResponseHandle *urh = users[i]->urh; 2335 users[i]->urh = NULL;
2338 if (NULL != urh) 2336 MHD_upgrade_action (users[i]->urh,
2339 { 2337 MHD_UPGRADE_ACTION_CLOSE);
2340 users[i]->urh = NULL;
2341 MHD_upgrade_action (users[i]->urh,
2342 MHD_UPGRADE_ACTION_CLOSE);
2343 }
2344 } 2338 }
2345 pthread_mutex_unlock (&chat_mutex);
2346 } 2339 }
2340 if (0 != pthread_mutex_unlock (&chat_mutex))
2341 abort ();
2347 sleep (2); 2342 sleep (2);
2348 2343
2349 /* usually we should wait here in a safe way for all threads to disconnect, */ 2344 /* usually we should wait here in a safe way for all threads to disconnect, */