diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-09-25 21:26:31 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-09-25 21:26:31 +0200 |
commit | 2212a372569ddbb2841ebbdb25260fac168fef23 (patch) | |
tree | 17e70c53203accbed03f082912a3995052534ba1 | |
parent | e42c783bb884dd7e9319236a3bcd3abb5819fce6 (diff) | |
download | libmicrohttpd-2212a372569ddbb2841ebbdb25260fac168fef23.tar.gz libmicrohttpd-2212a372569ddbb2841ebbdb25260fac168fef23.zip |
check rvalues from pthread_mutex_ operations in examples
-rw-r--r-- | src/examples/websocket_chatserver_example.c | 481 | ||||
-rw-r--r-- | src/examples/websocket_threaded_example.c | 18 |
2 files changed, 250 insertions, 249 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, */ |
diff --git a/src/examples/websocket_threaded_example.c b/src/examples/websocket_threaded_example.c index 4fcac79b..eec1f557 100644 --- a/src/examples/websocket_threaded_example.c +++ b/src/examples/websocket_threaded_example.c | |||
@@ -625,7 +625,8 @@ ws_send_frame (MHD_socket sock, const char *msg, size_t length) | |||
625 | } | 625 | } |
626 | response[idx_response] = '\0'; | 626 | response[idx_response] = '\0'; |
627 | output = 0; | 627 | output = 0; |
628 | pthread_mutex_lock (&MUTEX); | 628 | if (0 != pthread_mutex_lock (&MUTEX)) |
629 | abort (); | ||
629 | for (i = 0; i < MAX_CLIENTS; i++) | 630 | for (i = 0; i < MAX_CLIENTS; i++) |
630 | { | 631 | { |
631 | isock = CLIENT_SOCKS[i]; | 632 | isock = CLIENT_SOCKS[i]; |
@@ -634,7 +635,8 @@ ws_send_frame (MHD_socket sock, const char *msg, size_t length) | |||
634 | output += send_all (isock, response, idx_response); | 635 | output += send_all (isock, response, idx_response); |
635 | } | 636 | } |
636 | } | 637 | } |
637 | pthread_mutex_unlock (&MUTEX); | 638 | if (0 != pthread_mutex_unlock (&MUTEX)) |
639 | abort (); | ||
638 | free (response); | 640 | free (response); |
639 | return (ssize_t) output; | 641 | return (ssize_t) output; |
640 | } | 642 | } |
@@ -759,7 +761,8 @@ run_usock (void *cls) | |||
759 | } | 761 | } |
760 | } | 762 | } |
761 | } | 763 | } |
762 | pthread_mutex_lock (&MUTEX); | 764 | if (0 != pthread_mutex_lock (&MUTEX)) |
765 | abort (); | ||
763 | for (i = 0; i < MAX_CLIENTS; i++) | 766 | for (i = 0; i < MAX_CLIENTS; i++) |
764 | { | 767 | { |
765 | if (CLIENT_SOCKS[i] == ws->sock) | 768 | if (CLIENT_SOCKS[i] == ws->sock) |
@@ -768,7 +771,8 @@ run_usock (void *cls) | |||
768 | break; | 771 | break; |
769 | } | 772 | } |
770 | } | 773 | } |
771 | pthread_mutex_unlock (&MUTEX); | 774 | if (0 != pthread_mutex_unlock (&MUTEX)) |
775 | abort (); | ||
772 | free (ws); | 776 | free (ws); |
773 | MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE); | 777 | MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE); |
774 | return NULL; | 778 | return NULL; |
@@ -798,7 +802,8 @@ uh_cb (void *cls, struct MHD_Connection *con, void *req_cls, | |||
798 | ws->sock = sock; | 802 | ws->sock = sock; |
799 | ws->urh = urh; | 803 | ws->urh = urh; |
800 | sock_overflow = MHD_YES; | 804 | sock_overflow = MHD_YES; |
801 | pthread_mutex_lock (&MUTEX); | 805 | if (0 != pthread_mutex_lock (&MUTEX)) |
806 | abort (); | ||
802 | for (i = 0; i < MAX_CLIENTS; i++) | 807 | for (i = 0; i < MAX_CLIENTS; i++) |
803 | { | 808 | { |
804 | if (MHD_INVALID_SOCKET == CLIENT_SOCKS[i]) | 809 | if (MHD_INVALID_SOCKET == CLIENT_SOCKS[i]) |
@@ -808,7 +813,8 @@ uh_cb (void *cls, struct MHD_Connection *con, void *req_cls, | |||
808 | break; | 813 | break; |
809 | } | 814 | } |
810 | } | 815 | } |
811 | pthread_mutex_unlock (&MUTEX); | 816 | if (0 != pthread_mutex_unlock (&MUTEX)) |
817 | abort (); | ||
812 | if (sock_overflow) | 818 | if (sock_overflow) |
813 | { | 819 | { |
814 | free (ws); | 820 | free (ws); |