Changeset 132ab5d1 in mainline for uspace/lib/c/generic/async.c
- Timestamp:
- 2018-01-30T03:20:45Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5a6cc679
- Parents:
- 8bfb163 (diff), 6a5d05b (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/async.c
r8bfb163 r132ab5d1 77 77 * } 78 78 * 79 * port_handler(ic allid, *icall)79 * port_handler(ichandle, *icall) 80 80 * { 81 81 * if (want_refuse) { 82 * async_answer_0(ic allid, ELIMIT);82 * async_answer_0(ichandle, ELIMIT); 83 83 * return; 84 84 * } 85 * async_answer_0(ic allid, EOK);86 * 87 * c allid= async_get_call(&call);88 * somehow_handle_the_call(c allid, call);89 * async_answer_2(c allid, 1, 2, 3);90 * 91 * c allid= async_get_call(&call);85 * async_answer_0(ichandle, EOK); 86 * 87 * chandle = async_get_call(&call); 88 * somehow_handle_the_call(chandle, call); 89 * async_answer_2(chandle, 1, 2, 3); 90 * 91 * chandle = async_get_call(&call); 92 92 * ... 93 93 * } … … 113 113 #include <libarch/barrier.h> 114 114 #include <stdbool.h> 115 #include < malloc.h>115 #include <stdlib.h> 116 116 #include <mem.h> 117 117 #include <stdlib.h> … … 185 185 link_t link; 186 186 187 ipc_callid_t callid;187 cap_handle_t chandle; 188 188 ipc_call_t call; 189 189 } msg_t; … … 205 205 ipc_call_t *dataptr; 206 206 207 sysarg_t retval;207 int retval; 208 208 } amsg_t; 209 209 … … 237 237 238 238 /** Identification of the opening call. */ 239 ipc_callid_t callid;239 cap_handle_t chandle; 240 240 241 241 /** Call data of the opening call. */ … … 243 243 244 244 /** Identification of the closing call. */ 245 ipc_callid_t close_callid;245 cap_handle_t close_chandle; 246 246 247 247 /** Fibril function that will be used to handle the connection. */ … … 332 332 msg->destroyed = false; 333 333 msg->dataptr = NULL; 334 msg->retval = (sysarg_t)EINVAL;334 msg->retval = EINVAL; 335 335 awaiter_initialize(&msg->wdata); 336 336 } … … 374 374 /** Default fallback fibril function. 375 375 * 376 * This fallback fibril function gets called on incomming 377 * connections that donot have a specific handler defined.378 * 379 * @param c allid Hashof the incoming call.380 * @param call Data of the incoming call.381 * @param arg Local argument382 * 383 */ 384 static void default_fallback_port_handler( ipc_callid_t callid, ipc_call_t *call,385 void *arg)386 { 387 ipc_answer_0(c allid, ENOENT);376 * This fallback fibril function gets called on incomming connections that do 377 * not have a specific handler defined. 378 * 379 * @param chandle Handle of the incoming call. 380 * @param call Data of the incoming call. 381 * @param arg Local argument 382 * 383 */ 384 static void default_fallback_port_handler(cap_handle_t chandle, 385 ipc_call_t *call, void *arg) 386 { 387 ipc_answer_0(chandle, ENOENT); 388 388 } 389 389 … … 715 715 client_t *client = async_client_get(fibril_connection->in_task_id, true); 716 716 if (!client) { 717 ipc_answer_0(fibril_connection->c allid, ENOMEM);717 ipc_answer_0(fibril_connection->chandle, ENOMEM); 718 718 return 0; 719 719 } … … 724 724 * Call the connection handler function. 725 725 */ 726 fibril_connection->handler(fibril_connection->c allid,726 fibril_connection->handler(fibril_connection->chandle, 727 727 &fibril_connection->call, fibril_connection->data); 728 728 … … 751 751 752 752 list_remove(&msg->link); 753 ipc_answer_0(msg->c allid, EHANGUP);753 ipc_answer_0(msg->chandle, EHANGUP); 754 754 free(msg); 755 755 } … … 759 759 * i.e. IPC_M_PHONE_HUNGUP. 760 760 */ 761 if (fibril_connection->close_c allid)762 ipc_answer_0(fibril_connection->close_c allid, EOK);761 if (fibril_connection->close_chandle) 762 ipc_answer_0(fibril_connection->close_chandle, EOK); 763 763 764 764 free(fibril_connection); 765 return 0;765 return EOK; 766 766 } 767 767 768 768 /** Create a new fibril for a new connection. 769 769 * 770 * Create new fibril for connection, fill in connection structures 771 * and insert it into the hash table, so that later we can easily772 * do routing of messages toparticular fibrils.773 * 774 * @param in_task_id Identification of the incoming connection.775 * @param in_phone_hash Identification of the incoming connection.776 * @param c allid Hashof the opening IPC_M_CONNECT_ME_TO call.777 * If callid is zero, the connection was opened by778 * accepting the IPC_M_CONNECT_TO_ME call and this779 * function is called directly by the server.780 * @param call Call data of the opening call.781 * @param handler Connection handler.782 * @param data Client argument to pass to the connection handler.783 * 784 * @return New fibril id or NULL on failure.770 * Create new fibril for connection, fill in connection structures and insert it 771 * into the hash table, so that later we can easily do routing of messages to 772 * particular fibrils. 773 * 774 * @param in_task_id Identification of the incoming connection. 775 * @param in_phone_hash Identification of the incoming connection. 776 * @param chandle Handle of the opening IPC_M_CONNECT_ME_TO call. 777 * If chandle is CAP_NIL, the connection was opened by 778 * accepting the IPC_M_CONNECT_TO_ME call and this 779 * function is called directly by the server. 780 * @param call Call data of the opening call. 781 * @param handler Connection handler. 782 * @param data Client argument to pass to the connection handler. 783 * 784 * @return New fibril id or NULL on failure. 785 785 * 786 786 */ 787 787 static fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash, 788 ipc_callid_t callid, ipc_call_t *call, async_port_handler_t handler,788 cap_handle_t chandle, ipc_call_t *call, async_port_handler_t handler, 789 789 void *data) 790 790 { 791 791 connection_t *conn = malloc(sizeof(*conn)); 792 792 if (!conn) { 793 if (c allid)794 ipc_answer_0(c allid, ENOMEM);793 if (chandle != CAP_NIL) 794 ipc_answer_0(chandle, ENOMEM); 795 795 796 796 return (uintptr_t) NULL; … … 800 800 conn->in_phone_hash = in_phone_hash; 801 801 list_initialize(&conn->msg_queue); 802 conn->c allid = callid;803 conn->close_c allid = 0;802 conn->chandle = chandle; 803 conn->close_chandle = CAP_NIL; 804 804 conn->handler = handler; 805 805 conn->data = data; … … 815 815 free(conn); 816 816 817 if (c allid)818 ipc_answer_0(c allid, ENOMEM);817 if (chandle != CAP_NIL) 818 ipc_answer_0(chandle, ENOMEM); 819 819 820 820 return (uintptr_t) NULL; … … 844 844 * @param port_id ID of the newly created port. 845 845 * 846 * @return Zero on success or a negativeerror code.846 * @return Zero on success or an error code. 847 847 * 848 848 */ … … 860 860 &answer); 861 861 862 sysarg_t ret;862 int ret; 863 863 async_wait_for(req, &ret); 864 864 if (ret != EOK) … … 892 892 893 893 fid_t fid = async_new_connection(answer.in_task_id, phone_hash, 894 0, NULL, handler, data);894 CAP_NIL, NULL, handler, data); 895 895 if (fid == (uintptr_t) NULL) 896 896 return ENOMEM; … … 961 961 * timeouts are unregistered. 962 962 * 963 * @param c allid Hashof the incoming call.964 * @param call Data of the incoming call.963 * @param chandle Handle of the incoming call. 964 * @param call Data of the incoming call. 965 965 * 966 966 * @return False if the call doesn't match any connection. … … 968 968 * 969 969 */ 970 static bool route_call( ipc_callid_t callid, ipc_call_t *call)970 static bool route_call(cap_handle_t chandle, ipc_call_t *call) 971 971 { 972 972 assert(call); … … 991 991 } 992 992 993 msg->c allid = callid;993 msg->chandle = chandle; 994 994 msg->call = *call; 995 995 list_append(&msg->link, &conn->msg_queue); 996 996 997 997 if (IPC_GET_IMETHOD(*call) == IPC_M_PHONE_HUNGUP) 998 conn->close_c allid = callid;998 conn->close_chandle = chandle; 999 999 1000 1000 /* If the connection fibril is waiting for an event, activate it */ … … 1017 1017 /** Process notification. 1018 1018 * 1019 * @param callid Hash of the incoming call.1020 1019 * @param call Data of the incoming call. 1021 1020 * 1022 1021 */ 1023 static void process_notification(ipc_call id_t callid, ipc_call_t *call)1022 static void process_notification(ipc_call_t *call) 1024 1023 { 1025 1024 async_notification_handler_t handler = NULL; … … 1042 1041 1043 1042 if (handler) 1044 handler(call id, call, data);1043 handler(call, data); 1045 1044 } 1046 1045 … … 1052 1051 * @param ucode Top-half pseudocode handler. 1053 1052 * 1054 * @return IRQ capability handle on success. 1055 * @return Negative error code. 1053 * @param[out] handle IRQ capability handle on success. 1054 * 1055 * @return An error code. 1056 1056 * 1057 1057 */ 1058 1058 int async_irq_subscribe(int inr, async_notification_handler_t handler, 1059 void *data, const irq_code_t *ucode )1059 void *data, const irq_code_t *ucode, cap_handle_t *handle) 1060 1060 { 1061 1061 notification_t *notification = … … 1077 1077 futex_up(&async_futex); 1078 1078 1079 return ipc_irq_subscribe(inr, imethod, ucode); 1079 cap_handle_t cap; 1080 int rc = ipc_irq_subscribe(inr, imethod, ucode, &cap); 1081 if (rc == EOK && handle != NULL) { 1082 *handle = cap; 1083 } 1084 return rc; 1080 1085 } 1081 1086 … … 1084 1089 * @param cap IRQ capability handle. 1085 1090 * 1086 * @return Zero on success or a negativeerror code.1091 * @return Zero on success or an error code. 1087 1092 * 1088 1093 */ … … 1101 1106 * @param data Notification handler client data. 1102 1107 * 1103 * @return Zero on success or a negativeerror code.1108 * @return Zero on success or an error code. 1104 1109 * 1105 1110 */ … … 1134 1139 * @param data Notification handler client data. 1135 1140 * 1136 * @return Zero on success or a negativeerror code.1141 * @return Zero on success or an error code. 1137 1142 * 1138 1143 */ … … 1187 1192 /** Return new incoming message for the current (fibril-local) connection. 1188 1193 * 1189 * @param call Storage where the incoming call data will be stored. 1190 * @param usecs Timeout in microseconds. Zero denotes no timeout. 1191 * 1192 * @return If no timeout was specified, then a hash of the 1193 * incoming call is returned. If a timeout is specified, 1194 * then a hash of the incoming call is returned unless 1195 * the timeout expires prior to receiving a message. In 1196 * that case zero is returned. 1197 * 1198 */ 1199 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs) 1194 * @param call Storage where the incoming call data will be stored. 1195 * @param usecs Timeout in microseconds. Zero denotes no timeout. 1196 * 1197 * @return If no timeout was specified, then a handle of the incoming call is 1198 * returned. If a timeout is specified, then a handle of the incoming 1199 * call is returned unless the timeout expires prior to receiving a 1200 * message. In that case zero CAP_NIL is returned. 1201 */ 1202 cap_handle_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs) 1200 1203 { 1201 1204 assert(call); … … 1220 1223 /* If nothing in queue, wait until something arrives */ 1221 1224 while (list_empty(&conn->msg_queue)) { 1222 if (conn->close_c allid) {1225 if (conn->close_chandle) { 1223 1226 /* 1224 1227 * Handle the case when the connection was already … … 1231 1234 IPC_SET_IMETHOD(*call, IPC_M_PHONE_HUNGUP); 1232 1235 futex_up(&async_futex); 1233 return conn->close_c allid;1236 return conn->close_chandle; 1234 1237 } 1235 1238 … … 1256 1259 /* If we timed out -> exit */ 1257 1260 futex_up(&async_futex); 1258 return 0;1261 return CAP_NIL; 1259 1262 } 1260 1263 } … … 1264 1267 list_remove(&msg->link); 1265 1268 1266 ipc_callid_t callid = msg->callid;1269 cap_handle_t chandle = msg->chandle; 1267 1270 *call = msg->call; 1268 1271 free(msg); 1269 1272 1270 1273 futex_up(&async_futex); 1271 return c allid;1274 return chandle; 1272 1275 } 1273 1276 … … 1332 1335 * Otherwise the call is routed to its connection fibril. 1333 1336 * 1334 * @param c allid Hashof the incoming call.1335 * @param call Data of the incoming call.1336 * 1337 */ 1338 static void handle_call( ipc_callid_t callid, ipc_call_t *call)1337 * @param chandle Handle of the incoming call. 1338 * @param call Data of the incoming call. 1339 * 1340 */ 1341 static void handle_call(cap_handle_t chandle, ipc_call_t *call) 1339 1342 { 1340 1343 assert(call); 1341 1344 1342 1345 /* Kernel notification */ 1343 if ((c allid & IPC_CALLID_NOTIFICATION)) {1346 if ((chandle == CAP_NIL) && (call->flags & IPC_CALL_NOTIF)) { 1344 1347 fibril_t *fibril = (fibril_t *) __tcb_get()->fibril_data; 1345 1348 unsigned oldsw = fibril->switches; 1346 1349 1347 process_notification(call id, call);1350 process_notification(call); 1348 1351 1349 1352 if (oldsw != fibril->switches) { … … 1371 1374 sysarg_t in_phone_hash = IPC_GET_ARG5(*call); 1372 1375 1373 async_ notification_handler_t handler = fallback_port_handler;1376 async_port_handler_t handler = fallback_port_handler; 1374 1377 void *data = fallback_port_data; 1375 1378 … … 1381 1384 } 1382 1385 1383 async_new_connection(call->in_task_id, in_phone_hash, c allid,1386 async_new_connection(call->in_task_id, in_phone_hash, chandle, 1384 1387 call, handler, data); 1385 1388 return; … … 1387 1390 1388 1391 /* Try to route the call through the connection hash table */ 1389 if (route_call(c allid, call))1392 if (route_call(chandle, call)) 1390 1393 return; 1391 1394 1392 1395 /* Unknown call from unknown phone - hang it up */ 1393 ipc_answer_0(c allid, EHANGUP);1396 ipc_answer_0(chandle, EHANGUP); 1394 1397 } 1395 1398 … … 1486 1489 1487 1490 ipc_call_t call; 1488 i pc_callid_t callid= ipc_wait_cycle(&call, timeout, flags);1491 int rc = ipc_wait_cycle(&call, timeout, flags); 1489 1492 1490 1493 atomic_dec(&threads_in_ipc_wait); 1491 1494 1492 if (!callid) { 1493 handle_expired_timeouts(); 1495 assert(rc == EOK); 1496 1497 if (call.cap_handle == CAP_NIL) { 1498 if ((call.flags & 1499 (IPC_CALL_NOTIF | IPC_CALL_ANSWERED)) == 0) { 1500 /* Neither a notification nor an answer. */ 1501 handle_expired_timeouts(); 1502 continue; 1503 } 1504 } 1505 1506 if (call.flags & IPC_CALL_ANSWERED) 1494 1507 continue; 1495 } 1496 1497 if (callid & IPC_CALLID_ANSWERED) 1498 continue; 1499 1500 handle_call(callid, &call); 1501 } 1502 1508 1509 handle_call(call.cap_handle, &call); 1510 } 1511 1503 1512 return 0; 1504 1513 } … … 1631 1640 * @param arg3 Service-defined payload argument. 1632 1641 * @param arg4 Service-defined payload argument. 1633 * @param dataptr If non-NULL, storage where the reply data will be 1634 * stored. 1642 * @param dataptr If non-NULL, storage where the reply data will be stored. 1635 1643 * 1636 1644 * @return Hash of the sent message or 0 on error. … … 1701 1709 * 1702 1710 */ 1703 void async_wait_for(aid_t amsgid, sysarg_t *retval)1711 void async_wait_for(aid_t amsgid, int *retval) 1704 1712 { 1705 1713 assert(amsgid); … … 1747 1755 * 1748 1756 */ 1749 int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)1757 int async_wait_timeout(aid_t amsgid, int *retval, suseconds_t timeout) 1750 1758 { 1751 1759 assert(amsgid); … … 1848 1856 void async_usleep(suseconds_t timeout) 1849 1857 { 1850 amsg_t *msg = amsg_create(); 1851 if (!msg) 1852 return; 1853 1854 msg->wdata.fid = fibril_get_id(); 1855 1856 getuptime(&msg->wdata.to_event.expires); 1857 tv_add_diff(&msg->wdata.to_event.expires, timeout); 1858 awaiter_t awaiter; 1859 awaiter_initialize(&awaiter); 1860 1861 awaiter.fid = fibril_get_id(); 1862 1863 getuptime(&awaiter.to_event.expires); 1864 tv_add_diff(&awaiter.to_event.expires, timeout); 1858 1865 1859 1866 futex_down(&async_futex); 1860 1867 1861 async_insert_timeout(& msg->wdata);1868 async_insert_timeout(&awaiter); 1862 1869 1863 1870 /* Leave the async_futex locked when entering this function */ … … 1865 1872 1866 1873 /* Futex is up automatically after fibril_switch() */ 1867 1868 amsg_destroy(msg); 1874 } 1875 1876 /** Delay execution for the specified number of seconds 1877 * 1878 * @param sec Number of seconds to sleep 1879 */ 1880 void async_sleep(unsigned int sec) 1881 { 1882 /* 1883 * Sleep in 1000 second steps to support 1884 * full argument range 1885 */ 1886 1887 while (sec > 0) { 1888 unsigned int period = (sec > 1000) ? 1000 : sec; 1889 1890 async_usleep(period * 1000000); 1891 sec -= period; 1892 } 1869 1893 } 1870 1894 … … 1888 1912 * @param r5 If non-NULL, storage for the 5th reply argument. 1889 1913 * 1890 * @return Return code of the reply or a negativeerror code.1891 * 1892 */ 1893 sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,1914 * @return Return code of the reply or an error code. 1915 * 1916 */ 1917 int async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1894 1918 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, 1895 1919 sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) … … 1902 1926 &result); 1903 1927 1904 sysarg_t rc;1928 int rc; 1905 1929 async_wait_for(aid, &rc); 1906 1930 … … 1940 1964 * @param r5 If non-NULL, storage for the 5th reply argument. 1941 1965 * 1942 * @return Return code of the reply or a negativeerror code.1943 * 1944 */ 1945 sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,1966 * @return Return code of the reply or an error code. 1967 * 1968 */ 1969 int async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1946 1970 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, 1947 1971 sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) … … 1954 1978 &result); 1955 1979 1956 sysarg_t rc;1980 int rc; 1957 1981 async_wait_for(aid, &rc); 1958 1982 … … 2018 2042 } 2019 2043 2020 sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval)2021 { 2022 return ipc_answer_0(c allid, retval);2023 } 2024 2025 sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1)2026 { 2027 return ipc_answer_1(c allid, retval, arg1);2028 } 2029 2030 sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,2044 int async_answer_0(cap_handle_t chandle, int retval) 2045 { 2046 return ipc_answer_0(chandle, retval); 2047 } 2048 2049 int async_answer_1(cap_handle_t chandle, int retval, sysarg_t arg1) 2050 { 2051 return ipc_answer_1(chandle, retval, arg1); 2052 } 2053 2054 int async_answer_2(cap_handle_t chandle, int retval, sysarg_t arg1, 2031 2055 sysarg_t arg2) 2032 2056 { 2033 return ipc_answer_2(c allid, retval, arg1, arg2);2034 } 2035 2036 sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,2057 return ipc_answer_2(chandle, retval, arg1, arg2); 2058 } 2059 2060 int async_answer_3(cap_handle_t chandle, int retval, sysarg_t arg1, 2037 2061 sysarg_t arg2, sysarg_t arg3) 2038 2062 { 2039 return ipc_answer_3(c allid, retval, arg1, arg2, arg3);2040 } 2041 2042 sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,2063 return ipc_answer_3(chandle, retval, arg1, arg2, arg3); 2064 } 2065 2066 int async_answer_4(cap_handle_t chandle, int retval, sysarg_t arg1, 2043 2067 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 2044 2068 { 2045 return ipc_answer_4(c allid, retval, arg1, arg2, arg3, arg4);2046 } 2047 2048 sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,2069 return ipc_answer_4(chandle, retval, arg1, arg2, arg3, arg4); 2070 } 2071 2072 int async_answer_5(cap_handle_t chandle, int retval, sysarg_t arg1, 2049 2073 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 2050 2074 { 2051 return ipc_answer_5(c allid, retval, arg1, arg2, arg3, arg4, arg5);2052 } 2053 2054 int async_forward_fast( ipc_callid_t callid, async_exch_t *exch,2075 return ipc_answer_5(chandle, retval, arg1, arg2, arg3, arg4, arg5); 2076 } 2077 2078 int async_forward_fast(cap_handle_t chandle, async_exch_t *exch, 2055 2079 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode) 2056 2080 { … … 2058 2082 return ENOENT; 2059 2083 2060 return ipc_forward_fast(c allid, exch->phone, imethod, arg1, arg2, mode);2061 } 2062 2063 int async_forward_slow( ipc_callid_t callid, async_exch_t *exch,2084 return ipc_forward_fast(chandle, exch->phone, imethod, arg1, arg2, mode); 2085 } 2086 2087 int async_forward_slow(cap_handle_t chandle, async_exch_t *exch, 2064 2088 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 2065 2089 sysarg_t arg4, sysarg_t arg5, unsigned int mode) … … 2068 2092 return ENOENT; 2069 2093 2070 return ipc_forward_slow(c allid, exch->phone, imethod, arg1, arg2, arg3,2094 return ipc_forward_slow(chandle, exch->phone, imethod, arg1, arg2, arg3, 2071 2095 arg4, arg5, mode); 2072 2096 } … … 2081 2105 * @param arg3 User defined argument. 2082 2106 * 2083 * @return Zero on success or a negativeerror code.2107 * @return Zero on success or an error code. 2084 2108 * 2085 2109 */ … … 2094 2118 &answer); 2095 2119 2096 sysarg_t rc;2120 int rc; 2097 2121 async_wait_for(req, &rc); 2098 2122 if (rc != EOK) … … 2103 2127 2104 2128 static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2, 2105 sysarg_t arg3, sysarg_t arg4 )2129 sysarg_t arg3, sysarg_t arg4, int *out_phone) 2106 2130 { 2107 2131 ipc_call_t result; 2132 2133 // XXX: Workaround for GCC's inability to infer association between 2134 // rc == EOK and *out_phone being assigned. 2135 *out_phone = -1; 2108 2136 2109 2137 amsg_t *msg = amsg_create(); … … 2117 2145 msg, reply_received); 2118 2146 2119 sysarg_t rc;2147 int rc; 2120 2148 async_wait_for((aid_t) msg, &rc); 2121 2149 … … 2123 2151 return rc; 2124 2152 2125 return (int) IPC_GET_ARG5(result); 2153 *out_phone = (int) IPC_GET_ARG5(result); 2154 return EOK; 2126 2155 } 2127 2156 … … 2153 2182 } 2154 2183 2155 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 2156 0); 2157 if (phone < 0) { 2158 errno = phone; 2184 int phone; 2185 int rc = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 2186 0, &phone); 2187 if (rc != EOK) { 2188 errno = rc; 2159 2189 free(sess); 2160 2190 return NULL; … … 2205 2235 } 2206 2236 2207 int phone = async_connect_me_to_internal(exch->phone, iface, arg2, 2208 arg3, 0); 2209 if (phone < 0) { 2210 errno = phone; 2237 int phone; 2238 int rc = async_connect_me_to_internal(exch->phone, iface, arg2, 2239 arg3, 0, &phone); 2240 if (rc != EOK) { 2241 errno = rc; 2211 2242 free(sess); 2212 2243 return NULL; … … 2275 2306 } 2276 2307 2277 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 2278 IPC_FLAG_BLOCKING); 2279 2280 if (phone < 0) { 2281 errno = phone; 2308 int phone; 2309 int rc = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 2310 IPC_FLAG_BLOCKING, &phone); 2311 2312 if (rc != EOK) { 2313 errno = rc; 2282 2314 free(sess); 2283 2315 return NULL; … … 2328 2360 } 2329 2361 2330 int phone = async_connect_me_to_internal(exch->phone, iface, arg2, 2331 arg3, IPC_FLAG_BLOCKING); 2332 if (phone < 0) { 2333 errno = phone; 2362 int phone; 2363 int rc = async_connect_me_to_internal(exch->phone, iface, arg2, 2364 arg3, IPC_FLAG_BLOCKING, &phone); 2365 if (rc != EOK) { 2366 errno = rc; 2334 2367 free(sess); 2335 2368 return NULL; … … 2363 2396 } 2364 2397 2365 int phone = ipc_connect_kbox(id); 2366 if (phone < 0) { 2367 errno = phone; 2398 cap_handle_t phone; 2399 int rc = ipc_connect_kbox(id, &phone); 2400 if (rc != EOK) { 2401 errno = rc; 2368 2402 free(sess); 2369 2403 return NULL; … … 2396 2430 * @param sess Session to hung up. 2397 2431 * 2398 * @return Zero on success or a negativeerror code.2432 * @return Zero on success or an error code. 2399 2433 * 2400 2434 */ … … 2482 2516 } else if (mgmt == EXCHANGE_PARALLEL) { 2483 2517 int phone; 2518 int rc; 2484 2519 2485 2520 retry: … … 2487 2522 * Make a one-time attempt to connect a new data phone. 2488 2523 */ 2489 phone= async_connect_me_to_internal(sess->phone, sess->arg1,2490 sess->arg2, sess->arg3, 0 );2491 if ( phone >= 0) {2524 rc = async_connect_me_to_internal(sess->phone, sess->arg1, 2525 sess->arg2, sess->arg3, 0, &phone); 2526 if (rc == EOK) { 2492 2527 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 2493 2528 if (exch != NULL) { … … 2575 2610 * base address. Cannot be NULL. 2576 2611 * 2577 * @return Zero on success or a negativeerror code from errno.h.2612 * @return Zero on success or an error code from errno.h. 2578 2613 * 2579 2614 */ … … 2604 2639 * So far, this wrapper is to be used from within a connection fibril. 2605 2640 * 2606 * @param c allid Storage for the hashof the IPC_M_SHARE_IN call.2607 * @param size Destination address space area size.2641 * @param chandle Storage for the handle of the IPC_M_SHARE_IN call. 2642 * @param size Destination address space area size. 2608 2643 * 2609 2644 * @return True on success, false on failure. 2610 2645 * 2611 2646 */ 2612 bool async_share_in_receive( ipc_callid_t *callid, size_t *size)2613 { 2614 assert(c allid);2647 bool async_share_in_receive(cap_handle_t *chandle, size_t *size) 2648 { 2649 assert(chandle); 2615 2650 assert(size); 2616 2651 2617 2652 ipc_call_t data; 2618 *c allid= async_get_call(&data);2653 *chandle = async_get_call(&data); 2619 2654 2620 2655 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN) … … 2631 2666 * argument. 2632 2667 * 2633 * @param c allid Hashof the IPC_M_DATA_READ call to answer.2634 * @param src Source address space base.2635 * @param flags Flags to be used for sharing. Bits can be only cleared.2668 * @param chandle Handle of the IPC_M_DATA_READ call to answer. 2669 * @param src Source address space base. 2670 * @param flags Flags to be used for sharing. Bits can be only cleared. 2636 2671 * 2637 2672 * @return Zero on success or a value from @ref errno.h on failure. 2638 2673 * 2639 2674 */ 2640 int async_share_in_finalize( ipc_callid_t callid, void *src, unsigned int flags)2641 { 2642 return ipc_answer_3(c allid, EOK, (sysarg_t) src, (sysarg_t) flags,2675 int async_share_in_finalize(cap_handle_t chandle, void *src, unsigned int flags) 2676 { 2677 return ipc_answer_3(chandle, EOK, (sysarg_t) src, (sysarg_t) flags, 2643 2678 (sysarg_t) __entry); 2644 2679 } … … 2650 2685 * @param flags Flags to be used for sharing. Bits can be only cleared. 2651 2686 * 2652 * @return Zero on success or a negativeerror code from errno.h.2687 * @return Zero on success or an error code from errno.h. 2653 2688 * 2654 2689 */ … … 2670 2705 * So far, this wrapper is to be used from within a connection fibril. 2671 2706 * 2672 * @param c allidStorage for the hash of the IPC_M_SHARE_OUT call.2673 * @param size Storage for the source address space area size.2674 * @param flags Storage for the sharing flags.2707 * @param chandle Storage for the hash of the IPC_M_SHARE_OUT call. 2708 * @param size Storage for the source address space area size. 2709 * @param flags Storage for the sharing flags. 2675 2710 * 2676 2711 * @return True on success, false on failure. 2677 2712 * 2678 2713 */ 2679 bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags) 2680 { 2681 assert(callid); 2714 bool async_share_out_receive(cap_handle_t *chandle, size_t *size, 2715 unsigned int *flags) 2716 { 2717 assert(chandle); 2682 2718 assert(size); 2683 2719 assert(flags); 2684 2720 2685 2721 ipc_call_t data; 2686 *c allid= async_get_call(&data);2722 *chandle = async_get_call(&data); 2687 2723 2688 2724 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT) … … 2700 2736 * argument. 2701 2737 * 2702 * @param c allid Hashof the IPC_M_DATA_WRITE call to answer.2703 * @param dst Address of the storage for the destination address space area2704 * base address.2705 * 2706 * @return Zero on success or a value from @ref errno.h on failure.2707 * 2708 */ 2709 int async_share_out_finalize( ipc_callid_t callid, void **dst)2710 { 2711 return ipc_answer_2(c allid, EOK, (sysarg_t) __entry, (sysarg_t) dst);2738 * @param chandle Handle of the IPC_M_DATA_WRITE call to answer. 2739 * @param dst Address of the storage for the destination address space area 2740 * base address. 2741 * 2742 * @return Zero on success or a value from @ref errno.h on failure. 2743 * 2744 */ 2745 int async_share_out_finalize(cap_handle_t chandle, void **dst) 2746 { 2747 return ipc_answer_2(chandle, EOK, (sysarg_t) __entry, (sysarg_t) dst); 2712 2748 } 2713 2749 … … 2735 2771 * @param size Size of the destination buffer. 2736 2772 * 2737 * @return Zero on success or a negativeerror code from errno.h.2773 * @return Zero on success or an error code from errno.h. 2738 2774 * 2739 2775 */ … … 2755 2791 * So far, this wrapper is to be used from within a connection fibril. 2756 2792 * 2757 * @param c allid Storage for the hashof the IPC_M_DATA_READ.2758 * @param size Storage for the maximum size. Can be NULL.2793 * @param chandle Storage for the handle of the IPC_M_DATA_READ. 2794 * @param size Storage for the maximum size. Can be NULL. 2759 2795 * 2760 2796 * @return True on success, false on failure. 2761 2797 * 2762 2798 */ 2763 bool async_data_read_receive( ipc_callid_t *callid, size_t *size)2799 bool async_data_read_receive(cap_handle_t *chandle, size_t *size) 2764 2800 { 2765 2801 ipc_call_t data; 2766 return async_data_read_receive_call(c allid, &data, size);2802 return async_data_read_receive_call(chandle, &data, size); 2767 2803 } 2768 2804 … … 2775 2811 * So far, this wrapper is to be used from within a connection fibril. 2776 2812 * 2777 * @param c allid Storage for the hashof the IPC_M_DATA_READ.2778 * @param size Storage for the maximum size. Can be NULL.2813 * @param chandle Storage for the handle of the IPC_M_DATA_READ. 2814 * @param size Storage for the maximum size. Can be NULL. 2779 2815 * 2780 2816 * @return True on success, false on failure. 2781 2817 * 2782 2818 */ 2783 bool async_data_read_receive_call( ipc_callid_t *callid, ipc_call_t *data,2819 bool async_data_read_receive_call(cap_handle_t *chandle, ipc_call_t *data, 2784 2820 size_t *size) 2785 2821 { 2786 assert(c allid);2822 assert(chandle); 2787 2823 assert(data); 2788 2824 2789 *c allid= async_get_call(data);2825 *chandle = async_get_call(data); 2790 2826 2791 2827 if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_READ) … … 2804 2840 * argument. 2805 2841 * 2806 * @param c allid Hashof the IPC_M_DATA_READ call to answer.2807 * @param src Source address for the IPC_M_DATA_READ call.2808 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than2809 * the maximum size announced by the sender.2810 * 2811 * @return Zero on success or a value from @ref errno.h on failure.2812 * 2813 */ 2814 int async_data_read_finalize( ipc_callid_t callid, const void *src, size_t size)2815 { 2816 return ipc_answer_2(c allid, EOK, (sysarg_t) src, (sysarg_t) size);2842 * @param chandle Handle of the IPC_M_DATA_READ call to answer. 2843 * @param src Source address for the IPC_M_DATA_READ call. 2844 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 2845 * the maximum size announced by the sender. 2846 * 2847 * @return Zero on success or a value from @ref errno.h on failure. 2848 * 2849 */ 2850 int async_data_read_finalize(cap_handle_t chandle, const void *src, size_t size) 2851 { 2852 return ipc_answer_2(chandle, EOK, (sysarg_t) src, (sysarg_t) size); 2817 2853 } 2818 2854 … … 2827 2863 return ENOENT; 2828 2864 2829 ipc_callid_t callid;2830 if (!async_data_read_receive(&c allid, NULL)) {2831 ipc_answer_0(c allid, EINVAL);2865 cap_handle_t chandle; 2866 if (!async_data_read_receive(&chandle, NULL)) { 2867 ipc_answer_0(chandle, EINVAL); 2832 2868 return EINVAL; 2833 2869 } … … 2836 2872 dataptr); 2837 2873 if (msg == 0) { 2838 ipc_answer_0(c allid, EINVAL);2874 ipc_answer_0(chandle, EINVAL); 2839 2875 return EINVAL; 2840 2876 } 2841 2877 2842 int retval = ipc_forward_fast(c allid, exch->phone, 0, 0, 0,2878 int retval = ipc_forward_fast(chandle, exch->phone, 0, 0, 0, 2843 2879 IPC_FF_ROUTE_FROM_ME); 2844 2880 if (retval != EOK) { 2845 2881 async_forget(msg); 2846 ipc_answer_0(c allid, retval);2882 ipc_answer_0(chandle, retval); 2847 2883 return retval; 2848 2884 } 2849 2885 2850 sysarg_t rc;2886 int rc; 2851 2887 async_wait_for(msg, &rc); 2852 2888 … … 2860 2896 * @param size Size of the source buffer. 2861 2897 * 2862 * @return Zero on success or a negativeerror code from errno.h.2898 * @return Zero on success or an error code from errno.h. 2863 2899 * 2864 2900 */ … … 2880 2916 * So far, this wrapper is to be used from within a connection fibril. 2881 2917 * 2882 * @param c allid Storage for the hashof the IPC_M_DATA_WRITE.2883 * @param size Storage for the suggested size. May be NULL.2884 * 2885 * @return True on success, false on failure.2886 * 2887 */ 2888 bool async_data_write_receive( ipc_callid_t *callid, size_t *size)2918 * @param chandle Storage for the handle of the IPC_M_DATA_WRITE. 2919 * @param size Storage for the suggested size. May be NULL. 2920 * 2921 * @return True on success, false on failure. 2922 * 2923 */ 2924 bool async_data_write_receive(cap_handle_t *chandle, size_t *size) 2889 2925 { 2890 2926 ipc_call_t data; 2891 return async_data_write_receive_call(c allid, &data, size);2927 return async_data_write_receive_call(chandle, &data, size); 2892 2928 } 2893 2929 … … 2900 2936 * So far, this wrapper is to be used from within a connection fibril. 2901 2937 * 2902 * @param c allid Storage for the hashof the IPC_M_DATA_WRITE.2903 * @param data Storage for the ipc call data.2904 * @param size Storage for the suggested size. May be NULL.2938 * @param chandle Storage for the handle of the IPC_M_DATA_WRITE. 2939 * @param data Storage for the ipc call data. 2940 * @param size Storage for the suggested size. May be NULL. 2905 2941 * 2906 2942 * @return True on success, false on failure. 2907 2943 * 2908 2944 */ 2909 bool async_data_write_receive_call( ipc_callid_t *callid, ipc_call_t *data,2945 bool async_data_write_receive_call(cap_handle_t *chandle, ipc_call_t *data, 2910 2946 size_t *size) 2911 2947 { 2912 assert(c allid);2948 assert(chandle); 2913 2949 assert(data); 2914 2950 2915 *c allid= async_get_call(data);2951 *chandle = async_get_call(data); 2916 2952 2917 2953 if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_WRITE) … … 2930 2966 * argument. 2931 2967 * 2932 * @param c allid Hashof the IPC_M_DATA_WRITE call to answer.2933 * @param dst Final destination address for the IPC_M_DATA_WRITE call.2934 * @param size Final size for the IPC_M_DATA_WRITE call.2935 * 2936 * @return Zero on success or a value from @ref errno.h on failure.2937 * 2938 */ 2939 int async_data_write_finalize( ipc_callid_t callid, void *dst, size_t size)2940 { 2941 return ipc_answer_2(c allid, EOK, (sysarg_t) dst, (sysarg_t) size);2968 * @param chandle Handle of the IPC_M_DATA_WRITE call to answer. 2969 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 2970 * @param size Final size for the IPC_M_DATA_WRITE call. 2971 * 2972 * @return Zero on success or a value from @ref errno.h on failure. 2973 * 2974 */ 2975 int async_data_write_finalize(cap_handle_t chandle, void *dst, size_t size) 2976 { 2977 return ipc_answer_2(chandle, EOK, (sysarg_t) dst, (sysarg_t) size); 2942 2978 } 2943 2979 … … 2969 3005 assert(data); 2970 3006 2971 ipc_callid_t callid;3007 cap_handle_t chandle; 2972 3008 size_t size; 2973 if (!async_data_write_receive(&c allid, &size)) {2974 ipc_answer_0(c allid, EINVAL);3009 if (!async_data_write_receive(&chandle, &size)) { 3010 ipc_answer_0(chandle, EINVAL); 2975 3011 return EINVAL; 2976 3012 } 2977 3013 2978 3014 if (size < min_size) { 2979 ipc_answer_0(c allid, EINVAL);3015 ipc_answer_0(chandle, EINVAL); 2980 3016 return EINVAL; 2981 3017 } 2982 3018 2983 3019 if ((max_size > 0) && (size > max_size)) { 2984 ipc_answer_0(c allid, EINVAL);3020 ipc_answer_0(chandle, EINVAL); 2985 3021 return EINVAL; 2986 3022 } 2987 3023 2988 3024 if ((granularity > 0) && ((size % granularity) != 0)) { 2989 ipc_answer_0(c allid, EINVAL);3025 ipc_answer_0(chandle, EINVAL); 2990 3026 return EINVAL; 2991 3027 } … … 2999 3035 3000 3036 if (arg_data == NULL) { 3001 ipc_answer_0(c allid, ENOMEM);3037 ipc_answer_0(chandle, ENOMEM); 3002 3038 return ENOMEM; 3003 3039 } 3004 3040 3005 int rc = async_data_write_finalize(c allid, arg_data, size);3041 int rc = async_data_write_finalize(chandle, arg_data, size); 3006 3042 if (rc != EOK) { 3007 3043 free(arg_data); … … 3026 3062 * 3027 3063 */ 3028 void async_data_write_void( sysarg_t retval)3029 { 3030 ipc_callid_t callid;3031 async_data_write_receive(&c allid, NULL);3032 ipc_answer_0(c allid, retval);3064 void async_data_write_void(int retval) 3065 { 3066 cap_handle_t chandle; 3067 async_data_write_receive(&chandle, NULL); 3068 ipc_answer_0(chandle, retval); 3033 3069 } 3034 3070 … … 3043 3079 return ENOENT; 3044 3080 3045 ipc_callid_t callid;3046 if (!async_data_write_receive(&c allid, NULL)) {3047 ipc_answer_0(c allid, EINVAL);3081 cap_handle_t chandle; 3082 if (!async_data_write_receive(&chandle, NULL)) { 3083 ipc_answer_0(chandle, EINVAL); 3048 3084 return EINVAL; 3049 3085 } … … 3052 3088 dataptr); 3053 3089 if (msg == 0) { 3054 ipc_answer_0(c allid, EINVAL);3090 ipc_answer_0(chandle, EINVAL); 3055 3091 return EINVAL; 3056 3092 } 3057 3093 3058 int retval = ipc_forward_fast(c allid, exch->phone, 0, 0, 0,3094 int retval = ipc_forward_fast(chandle, exch->phone, 0, 0, 0, 3059 3095 IPC_FF_ROUTE_FROM_ME); 3060 3096 if (retval != EOK) { 3061 3097 async_forget(msg); 3062 ipc_answer_0(c allid, retval);3098 ipc_answer_0(chandle, retval); 3063 3099 return retval; 3064 3100 } 3065 3101 3066 sysarg_t rc;3102 int rc; 3067 3103 async_wait_for(msg, &rc); 3068 3104 … … 3085 3121 /* Accept the phone */ 3086 3122 ipc_call_t call; 3087 ipc_callid_t callid = async_get_call(&call); 3088 int phone = (int) IPC_GET_ARG5(call); 3089 3090 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) || 3091 (phone < 0)) { 3092 async_answer_0(callid, EINVAL); 3123 cap_handle_t chandle = async_get_call(&call); 3124 cap_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call); 3125 3126 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) || (phandle < 0)) { 3127 async_answer_0(chandle, EINVAL); 3093 3128 return NULL; 3094 3129 } … … 3096 3131 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 3097 3132 if (sess == NULL) { 3098 async_answer_0(c allid, ENOMEM);3133 async_answer_0(chandle, ENOMEM); 3099 3134 return NULL; 3100 3135 } … … 3102 3137 sess->iface = 0; 3103 3138 sess->mgmt = mgmt; 3104 sess->phone = ph one;3139 sess->phone = phandle; 3105 3140 sess->arg1 = 0; 3106 3141 sess->arg2 = 0; … … 3115 3150 3116 3151 /* Acknowledge the connected phone */ 3117 async_answer_0(c allid, EOK);3152 async_answer_0(chandle, EOK); 3118 3153 3119 3154 return sess; … … 3136 3171 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call) 3137 3172 { 3138 int phone = (int) IPC_GET_ARG5(*call); 3139 3140 if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) || 3141 (phone < 0)) 3173 cap_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*call); 3174 3175 if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) || (phandle < 0)) 3142 3176 return NULL; 3143 3177 … … 3148 3182 sess->iface = 0; 3149 3183 sess->mgmt = mgmt; 3150 sess->phone = ph one;3184 sess->phone = phandle; 3151 3185 sess->arg1 = 0; 3152 3186 sess->arg2 = 0; … … 3170 3204 } 3171 3205 3172 bool async_state_change_receive( ipc_callid_t *callid, sysarg_t *arg1,3206 bool async_state_change_receive(cap_handle_t *chandle, sysarg_t *arg1, 3173 3207 sysarg_t *arg2, sysarg_t *arg3) 3174 3208 { 3175 assert(c allid);3209 assert(chandle); 3176 3210 3177 3211 ipc_call_t call; 3178 *c allid= async_get_call(&call);3212 *chandle = async_get_call(&call); 3179 3213 3180 3214 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE) … … 3191 3225 } 3192 3226 3193 int async_state_change_finalize( ipc_callid_t callid, async_exch_t *other_exch)3194 { 3195 return ipc_answer_1(c allid, EOK, other_exch->phone);3227 int async_state_change_finalize(cap_handle_t chandle, async_exch_t *other_exch) 3228 { 3229 return ipc_answer_1(chandle, EOK, other_exch->phone); 3196 3230 } 3197 3231
Note:
See TracChangeset
for help on using the changeset viewer.