Changeset 93fb170c in mainline for uspace/lib/c/generic/net/socket_client.c
- Timestamp:
- 2011-01-08T18:51:31Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 15be932
- Parents:
- 8f748215 (diff), a523af4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/net/socket_client.c
r8f748215 r93fb170c 220 220 fibril_rwlock_read_lock(&socket_globals.lock); 221 221 222 / / find the socket222 /* Find the socket */ 223 223 socket = sockets_find(socket_get_sockets(), 224 224 SOCKET_GET_SOCKET_ID(call)); … … 232 232 case NET_SOCKET_RECEIVED: 233 233 fibril_mutex_lock(&socket->receive_lock); 234 / / push the number of received packet fragments234 /* Push the number of received packet fragments */ 235 235 rc = dyn_fifo_push(&socket->received, 236 236 SOCKET_GET_DATA_FRAGMENTS(call), 237 237 SOCKET_MAX_RECEIVED_SIZE); 238 238 if (rc == EOK) { 239 / / signal the received packet239 /* Signal the received packet */ 240 240 fibril_condvar_signal(&socket->receive_signal); 241 241 } … … 244 244 245 245 case NET_SOCKET_ACCEPTED: 246 / / push the new socket identifier246 /* Push the new socket identifier */ 247 247 fibril_mutex_lock(&socket->accept_lock); 248 248 rc = dyn_fifo_push(&socket->accepted, 1, 249 249 SOCKET_MAX_ACCEPTED_SIZE); 250 250 if (rc == EOK) { 251 / / signal the accepted socket251 /* Signal the accepted socket */ 252 252 fibril_condvar_signal(&socket->accept_signal); 253 253 } … … 264 264 fibril_rwlock_write_lock(&socket->sending_lock); 265 265 266 / / set the data fragment size266 /* Set the data fragment size */ 267 267 socket->data_fragment_size = 268 268 SOCKET_GET_DATA_FRAGMENT_SIZE(call); … … 342 342 socket_id = 1; 343 343 ++count; 344 / / only this branch for last_id344 /* Only this branch for last_id */ 345 345 } else { 346 346 if (socket_id < INT_MAX) { … … 408 408 int rc; 409 409 410 / / find the appropriate service410 /* Find the appropriate service */ 411 411 switch (domain) { 412 412 case PF_INET: … … 457 457 return phone; 458 458 459 / / create a new socket structure459 /* Create a new socket structure */ 460 460 socket = (socket_t *) malloc(sizeof(socket_t)); 461 461 if (!socket) … … 465 465 fibril_rwlock_write_lock(&socket_globals.lock); 466 466 467 / / request a new socket467 /* Request a new socket */ 468 468 socket_id = socket_generate_new_id(); 469 469 if (socket_id <= 0) { … … 484 484 socket->header_size = (size_t) header_size; 485 485 486 / / finish the new socket initialization486 /* Finish the new socket initialization */ 487 487 socket_initialize(socket, socket_id, phone, service); 488 / / store the new socket488 /* Store the new socket */ 489 489 rc = sockets_add(socket_get_sockets(), socket_id, socket); 490 490 … … 531 531 fibril_rwlock_read_lock(&socket_globals.lock); 532 532 533 / / find the socket533 /* Find the socket */ 534 534 socket = sockets_find(socket_get_sockets(), socket_id); 535 535 if (!socket) { … … 538 538 } 539 539 540 / / request the message540 /* Request the message */ 541 541 message_id = async_send_3(socket->phone, message, 542 542 (sysarg_t) socket->socket_id, arg2, socket->service, NULL); 543 / / send the address543 /* Send the address */ 544 544 async_data_write_start(socket->phone, data, datalength); 545 545 … … 566 566 return EINVAL; 567 567 568 / / send the address568 /* Send the address */ 569 569 return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, 570 570 (size_t) addrlen); … … 591 591 fibril_rwlock_read_lock(&socket_globals.lock); 592 592 593 / / find the socket593 /* Find the socket */ 594 594 socket = sockets_find(socket_get_sockets(), socket_id); 595 595 if (!socket) { … … 598 598 } 599 599 600 / / request listen backlog change600 /* Request listen backlog change */ 601 601 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, 602 602 (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service); … … 634 634 fibril_rwlock_write_lock(&socket_globals.lock); 635 635 636 / / find the socket636 /* Find the socket */ 637 637 socket = sockets_find(socket_get_sockets(), socket_id); 638 638 if (!socket) { … … 643 643 fibril_mutex_lock(&socket->accept_lock); 644 644 645 / / wait for an accepted socket645 /* Wait for an accepted socket */ 646 646 ++ socket->blocked; 647 647 while (dyn_fifo_value(&socket->accepted) <= 0) { 648 648 fibril_rwlock_write_unlock(&socket_globals.lock); 649 649 fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock); 650 / / drop the accept lock to avoid deadlock650 /* Drop the accept lock to avoid deadlock */ 651 651 fibril_mutex_unlock(&socket->accept_lock); 652 652 fibril_rwlock_write_lock(&socket_globals.lock); … … 655 655 -- socket->blocked; 656 656 657 / / create a new scoket657 /* Create a new socket */ 658 658 new_socket = (socket_t *) malloc(sizeof(socket_t)); 659 659 if (!new_socket) { … … 681 681 } 682 682 683 / / request accept683 /* Request accept */ 684 684 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, 685 685 (sysarg_t) socket->socket_id, 0, socket->service, 0, 686 686 new_socket->socket_id, &answer); 687 687 688 / / read address688 /* Read address */ 689 689 ipc_data_read_start(socket->phone, cliaddr, *addrlen); 690 690 fibril_rwlock_write_unlock(&socket_globals.lock); … … 695 695 result = EINVAL; 696 696 697 / / dequeue the accepted socket if successful697 /* Dequeue the accepted socket if successful */ 698 698 dyn_fifo_pop(&socket->accepted); 699 / / set address length699 /* Set address length */ 700 700 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 701 701 new_socket->data_fragment_size = 702 702 SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 703 703 } else if (result == ENOTSOCK) { 704 / / empty the queue if no accepted sockets704 /* Empty the queue if no accepted sockets */ 705 705 while (dyn_fifo_pop(&socket->accepted) > 0) 706 706 ; … … 731 731 return EDESTADDRREQ; 732 732 733 / / send the address733 /* Send the address */ 734 734 return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, 735 735 addrlen); … … 744 744 int accepted_id; 745 745 746 / / destroy all accepted sockets746 /* Destroy all accepted sockets */ 747 747 while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0) 748 748 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); … … 780 780 } 781 781 782 / / request close782 /* Request close */ 783 783 rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, 784 784 (sysarg_t) socket->socket_id, 0, socket->service); … … 787 787 return rc; 788 788 } 789 / / free the socket structure789 /* Free the socket structure */ 790 790 socket_destroy(socket); 791 791 … … 833 833 fibril_rwlock_read_lock(&socket_globals.lock); 834 834 835 / / find socket835 /* Find socket */ 836 836 socket = sockets_find(socket_get_sockets(), socket_id); 837 837 if (!socket) { … … 842 842 fibril_rwlock_read_lock(&socket->sending_lock); 843 843 844 / / compute data fragment count844 /* Compute data fragment count */ 845 845 if (socket->data_fragment_size > 0) { 846 846 fragments = (datalength + socket->header_size) / … … 853 853 } 854 854 855 / / request send855 /* Request send */ 856 856 message_id = async_send_5(socket->phone, message, 857 857 (sysarg_t) socket->socket_id, … … 859 859 socket->service, (sysarg_t) flags, fragments, &answer); 860 860 861 / / send the address if given861 /* Send the address if given */ 862 862 if (!toaddr || 863 863 (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) { 864 864 if (fragments == 1) { 865 / / send all if only one fragment865 /* Send all if only one fragment */ 866 866 async_data_write_start(socket->phone, data, datalength); 867 867 } else { 868 / / send the first fragment868 /* Send the first fragment */ 869 869 async_data_write_start(socket->phone, data, 870 870 socket->data_fragment_size - socket->header_size); … … 872 872 socket->data_fragment_size - socket->header_size; 873 873 874 / / send the middle fragments874 /* Send the middle fragments */ 875 875 while (--fragments > 1) { 876 876 async_data_write_start(socket->phone, data, … … 880 880 } 881 881 882 / / send the last fragment882 /* Send the last fragment */ 883 883 async_data_write_start(socket->phone, data, 884 884 (datalength + socket->header_size) % … … 892 892 (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != 893 893 socket->data_fragment_size)) { 894 / / set the data fragment size894 /* Set the data fragment size */ 895 895 socket->data_fragment_size = 896 896 SOCKET_GET_DATA_FRAGMENT_SIZE(answer); … … 917 917 int send(int socket_id, void *data, size_t datalength, int flags) 918 918 { 919 / / without the address919 /* Without the address */ 920 920 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, 921 921 NULL, 0); … … 950 950 return EDESTADDRREQ; 951 951 952 / / with the address952 /* With the address */ 953 953 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, 954 954 flags, toaddr, addrlen); … … 966 966 * read. The actual address length is set. Used only if 967 967 * fromaddr is not NULL. 968 * @return EOK on success. 968 * @return Positive received message size in bytes on success. 969 * @return Zero if no more data (other side closed the connection). 969 970 * @return ENOTSOCK if the socket is not found. 970 971 * @return EBADMEM if the data parameter is NULL. … … 972 973 * @return Other error codes as defined for the spcific message. 973 974 */ 974 static int975 static ssize_t 975 976 recvfrom_core(sysarg_t message, int socket_id, void *data, size_t datalength, 976 977 int flags, struct sockaddr *fromaddr, socklen_t *addrlen) … … 984 985 size_t index; 985 986 ipc_call_t answer; 987 ssize_t retval; 986 988 987 989 if (!data) … … 996 998 fibril_rwlock_read_lock(&socket_globals.lock); 997 999 998 / / find the socket1000 /* Find the socket */ 999 1001 socket = sockets_find(socket_get_sockets(), socket_id); 1000 1002 if (!socket) { … … 1004 1006 1005 1007 fibril_mutex_lock(&socket->receive_lock); 1006 / / wait for a received packet1008 /* Wait for a received packet */ 1007 1009 ++socket->blocked; 1008 while ((result = dyn_fifo_value(&socket->received)) < =0) {1010 while ((result = dyn_fifo_value(&socket->received)) < 0) { 1009 1011 fibril_rwlock_read_unlock(&socket_globals.lock); 1010 1012 fibril_condvar_wait(&socket->receive_signal, 1011 1013 &socket->receive_lock); 1012 1014 1013 / / drop the receive lock to avoid deadlock1015 /* Drop the receive lock to avoid deadlock */ 1014 1016 fibril_mutex_unlock(&socket->receive_lock); 1015 1017 fibril_rwlock_read_lock(&socket_globals.lock); … … 1019 1021 fragments = (size_t) result; 1020 1022 1021 // prepare lengths if more fragments 1023 if (fragments == 0) { 1024 /* No more data, other side has closed the connection. */ 1025 fibril_mutex_unlock(&socket->receive_lock); 1026 fibril_rwlock_read_unlock(&socket_globals.lock); 1027 return 0; 1028 } 1029 1030 /* Prepare lengths if more fragments */ 1022 1031 if (fragments > 1) { 1023 1032 lengths = (size_t *) malloc(sizeof(size_t) * fragments + … … 1029 1038 } 1030 1039 1031 / / request packet data1040 /* Request packet data */ 1032 1041 message_id = async_send_4(socket->phone, message, 1033 1042 (sysarg_t) socket->socket_id, 0, socket->service, 1034 1043 (sysarg_t) flags, &answer); 1035 1044 1036 / / read the address if desired1045 /* Read the address if desired */ 1037 1046 if(!fromaddr || 1038 1047 (async_data_read_start(socket->phone, fromaddr, 1039 1048 *addrlen) == EOK)) { 1040 / / read the fragment lengths1049 /* Read the fragment lengths */ 1041 1050 if (async_data_read_start(socket->phone, lengths, 1042 1051 sizeof(int) * (fragments + 1)) == EOK) { 1043 1052 if (lengths[fragments] <= datalength) { 1044 1053 1045 / / read all fragments if long enough1054 /* Read all fragments if long enough */ 1046 1055 for (index = 0; index < fragments; 1047 1056 ++index) { … … 1057 1066 1058 1067 free(lengths); 1059 } else { 1060 / / request packet data1068 } else { /* fragments == 1 */ 1069 /* Request packet data */ 1061 1070 message_id = async_send_4(socket->phone, message, 1062 1071 (sysarg_t) socket->socket_id, 0, socket->service, 1063 1072 (sysarg_t) flags, &answer); 1064 1073 1065 / / read the address if desired1074 /* Read the address if desired */ 1066 1075 if (!fromaddr || 1067 1076 (async_data_read_start(socket->phone, fromaddr, 1068 1077 *addrlen) == EOK)) { 1069 / / read all if only one fragment1078 /* Read all if only one fragment */ 1070 1079 async_data_read_start(socket->phone, data, datalength); 1071 1080 } … … 1075 1084 result = (int) ipc_result; 1076 1085 if (result == EOK) { 1077 / / dequeue the received packet1086 /* Dequeue the received packet */ 1078 1087 dyn_fifo_pop(&socket->received); 1079 / / return read data length1080 re sult= SOCKET_GET_READ_DATA_LENGTH(answer);1081 / / set address length1088 /* Return read data length */ 1089 retval = SOCKET_GET_READ_DATA_LENGTH(answer); 1090 /* Set address length */ 1082 1091 if (fromaddr && addrlen) 1083 1092 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 1093 } else { 1094 retval = (ssize_t) result; 1084 1095 } 1085 1096 1086 1097 fibril_mutex_unlock(&socket->receive_lock); 1087 1098 fibril_rwlock_read_unlock(&socket_globals.lock); 1088 return re sult;1099 return retval; 1089 1100 } 1090 1101 … … 1095 1106 * @param[in] datalength The data length. 1096 1107 * @param[in] flags Various receive flags. 1097 * @return EOK on success. 1108 * @return Positive received message size in bytes on success. 1109 * @return Zero if no more data (other side closed the connection). 1098 1110 * @return ENOTSOCK if the socket is not found. 1099 1111 * @return EBADMEM if the data parameter is NULL. … … 1102 1114 * message. 1103 1115 */ 1104 int recv(int socket_id, void *data, size_t datalength, int flags)1105 { 1106 / / without the address1116 ssize_t recv(int socket_id, void *data, size_t datalength, int flags) 1117 { 1118 /* Without the address */ 1107 1119 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, 1108 1120 flags, NULL, NULL); … … 1118 1130 * @param[in,out] addrlen The address length. The maximum address length is 1119 1131 * read. The actual address length is set. 1120 * @return EOK on success. 1132 * @return Positive received message size in bytes on success. 1133 * @return Zero if no more data (other side closed the connection). 1121 1134 * @return ENOTSOCK if the socket is not found. 1122 1135 * @return EBADMEM if the data or fromaddr parameter is NULL. … … 1125 1138 * message. 1126 1139 */ 1127 int1140 ssize_t 1128 1141 recvfrom(int socket_id, void *data, size_t datalength, int flags, 1129 1142 struct sockaddr *fromaddr, socklen_t *addrlen) … … 1135 1148 return NO_DATA; 1136 1149 1137 / / with the address1150 /* With the address */ 1138 1151 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, 1139 1152 flags, fromaddr, addrlen); … … 1170 1183 fibril_rwlock_read_lock(&socket_globals.lock); 1171 1184 1172 / / find the socket1185 /* Find the socket */ 1173 1186 socket = sockets_find(socket_get_sockets(), socket_id); 1174 1187 if (!socket) { … … 1177 1190 } 1178 1191 1179 / / request option value1192 /* Request option value */ 1180 1193 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, 1181 1194 (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service, 1182 1195 NULL); 1183 1196 1184 / / read the length1197 /* Read the length */ 1185 1198 if (async_data_read_start(socket->phone, optlen, 1186 1199 sizeof(*optlen)) == EOK) { 1187 / / read the value1200 /* Read the value */ 1188 1201 async_data_read_start(socket->phone, value, *optlen); 1189 1202 } … … 1212 1225 size_t optlen) 1213 1226 { 1214 / / send the value1227 /* Send the value */ 1215 1228 return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, 1216 1229 (sysarg_t) optname, value, optlen);
Note:
See TracChangeset
for help on using the changeset viewer.