Changeset 8565a42 in mainline for uspace/lib/c/generic/async.c
- Timestamp:
- 2018-03-02T20:34:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a1a81f69, d5e5fd1
- Parents:
- 3061bc1 (diff), 34e1206 (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. - git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:34:50)
- git-committer:
- GitHub <noreply@…> (2018-03-02 20:34:50)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r3061bc1 r8565a42 125 125 /** List of inactive exchanges */ 126 126 list_t exch_list; 127 127 128 128 /** Session interface */ 129 129 iface_t iface; 130 130 131 131 /** Exchange management style */ 132 132 exch_mgmt_t mgmt; 133 133 134 134 /** Session identification */ 135 135 int phone; 136 136 137 137 /** First clone connection argument */ 138 138 sysarg_t arg1; 139 139 140 140 /** Second clone connection argument */ 141 141 sysarg_t arg2; 142 142 143 143 /** Third clone connection argument */ 144 144 sysarg_t arg3; 145 145 146 146 /** Exchange mutex */ 147 147 fibril_mutex_t mutex; 148 148 149 149 /** Number of opened exchanges */ 150 150 atomic_t refcnt; 151 151 152 152 /** Mutex for stateful connections */ 153 153 fibril_mutex_t remote_state_mtx; 154 154 155 155 /** Data for stateful connections */ 156 156 void *remote_state_data; … … 161 161 /** Link into list of inactive exchanges */ 162 162 link_t sess_link; 163 163 164 164 /** Link into global list of inactive exchanges */ 165 165 link_t global_link; 166 166 167 167 /** Session pointer */ 168 168 async_sess_t *sess; 169 169 170 170 /** Exchange identification */ 171 171 int phone; … … 184 184 typedef struct { 185 185 link_t link; 186 186 187 187 cap_handle_t chandle; 188 188 ipc_call_t call; … … 192 192 typedef struct { 193 193 awaiter_t wdata; 194 194 195 195 /** If reply was received. */ 196 196 bool done; 197 197 198 198 /** If the message / reply should be discarded on arrival. */ 199 199 bool forget; 200 200 201 201 /** If already destroyed. */ 202 202 bool destroyed; 203 203 204 204 /** Pointer to where the answer data is stored. */ 205 205 ipc_call_t *dataptr; 206 206 207 207 errno_t retval; 208 208 } amsg_t; … … 211 211 typedef struct { 212 212 ht_link_t link; 213 213 214 214 task_id_t in_task_id; 215 215 atomic_t refcnt; … … 220 220 typedef struct { 221 221 awaiter_t wdata; 222 222 223 223 /** Hash table link. */ 224 224 ht_link_t link; 225 225 226 226 /** Incoming client task ID. */ 227 227 task_id_t in_task_id; 228 228 229 229 /** Incoming phone hash. */ 230 230 sysarg_t in_phone_hash; 231 231 232 232 /** Link to the client tracking structure. */ 233 233 client_t *client; 234 234 235 235 /** Messages that should be delivered to this fibril. */ 236 236 list_t msg_queue; 237 237 238 238 /** Identification of the opening call. */ 239 239 cap_handle_t chandle; 240 240 241 241 /** Call data of the opening call. */ 242 242 ipc_call_t call; 243 243 244 244 /** Identification of the closing call. */ 245 245 cap_handle_t close_chandle; 246 246 247 247 /** Fibril function that will be used to handle the connection. */ 248 248 async_port_handler_t handler; 249 249 250 250 /** Client data */ 251 251 void *data; … … 255 255 typedef struct { 256 256 ht_link_t link; 257 257 258 258 /** Interface ID */ 259 259 iface_t iface; 260 260 261 261 /** Futex protecting the hash table */ 262 262 futex_t futex; 263 263 264 264 /** Interface ports */ 265 265 hash_table_t port_hash_table; 266 266 267 267 /** Next available port ID */ 268 268 port_id_t port_id_avail; … … 272 272 typedef struct { 273 273 ht_link_t link; 274 274 275 275 /** Port ID */ 276 276 port_id_t id; 277 277 278 278 /** Port connection handler */ 279 279 async_port_handler_t handler; 280 280 281 281 /** Client data */ 282 282 void *data; … … 286 286 typedef struct { 287 287 ht_link_t link; 288 288 289 289 /** Notification method */ 290 290 sysarg_t imethod; 291 291 292 292 /** Notification handler */ 293 293 async_notification_handler_t handler; 294 294 295 295 /** Notification data */ 296 296 void *data; … … 303 303 { 304 304 struct timeval tv = { 0, 0 }; 305 305 306 306 to->inlist = false; 307 307 to->occurred = false; … … 335 335 awaiter_initialize(&msg->wdata); 336 336 } 337 337 338 338 return msg; 339 339 } … … 456 456 if (!interface) 457 457 return NULL; 458 458 459 459 bool ret = hash_table_create(&interface->port_hash_table, 0, 0, 460 460 &port_hash_table_ops); … … 463 463 return NULL; 464 464 } 465 465 466 466 interface->iface = iface; 467 467 futex_initialize(&interface->futex, 1); 468 468 interface->port_id_avail = 0; 469 469 470 470 hash_table_insert(&interface_hash_table, &interface->link); 471 471 472 472 return interface; 473 473 } … … 479 479 if (!port) 480 480 return NULL; 481 481 482 482 futex_down(&interface->futex); 483 483 484 484 port_id_t id = interface->port_id_avail; 485 485 interface->port_id_avail++; 486 486 487 487 port->id = id; 488 488 port->handler = handler; 489 489 port->data = data; 490 490 491 491 hash_table_insert(&interface->port_hash_table, &port->link); 492 492 493 493 futex_up(&interface->futex); 494 494 495 495 return port; 496 496 } … … 516 516 if ((iface & IFACE_MOD_MASK) == IFACE_MOD_CALLBACK) 517 517 return EINVAL; 518 518 519 519 interface_t *interface; 520 520 521 521 futex_down(&async_futex); 522 522 523 523 ht_link_t *link = hash_table_find(&interface_hash_table, &iface); 524 524 if (link) … … 526 526 else 527 527 interface = async_new_interface(iface); 528 528 529 529 if (!interface) { 530 530 futex_up(&async_futex); 531 531 return ENOMEM; 532 532 } 533 533 534 534 port_t *port = async_new_port(interface, handler, data); 535 535 if (!port) { … … 537 537 return ENOMEM; 538 538 } 539 539 540 540 *port_id = port->id; 541 541 542 542 futex_up(&async_futex); 543 543 544 544 return EOK; 545 545 } … … 548 548 { 549 549 assert(handler != NULL); 550 550 551 551 fallback_port_handler = handler; 552 552 fallback_port_data = data; … … 645 645 { 646 646 client_t *client = NULL; 647 647 648 648 futex_down(&async_futex); 649 649 ht_link_t *link = hash_table_find(&client_hash_table, &client_id); … … 656 656 client->in_task_id = client_id; 657 657 client->data = async_client_data_create(); 658 658 659 659 atomic_set(&client->refcnt, 1); 660 660 hash_table_insert(&client_hash_table, &client->link); 661 661 } 662 662 } 663 663 664 664 futex_up(&async_futex); 665 665 return client; … … 669 669 { 670 670 bool destroy; 671 671 672 672 futex_down(&async_futex); 673 673 674 674 if (atomic_predec(&client->refcnt) == 0) { 675 675 hash_table_remove(&client_hash_table, &client->in_task_id); … … 677 677 } else 678 678 destroy = false; 679 679 680 680 futex_up(&async_futex); 681 681 682 682 if (destroy) { 683 683 if (client->data) 684 684 async_client_data_destroy(client->data); 685 685 686 686 free(client); 687 687 } … … 701 701 { 702 702 assert(arg); 703 703 704 704 /* 705 705 * Setup fibril-local connection pointer. 706 706 */ 707 707 fibril_connection = (connection_t *) arg; 708 708 709 709 /* 710 710 * Add our reference for the current connection in the client task … … 712 712 * hash in a new tracking structure. 713 713 */ 714 714 715 715 client_t *client = async_client_get(fibril_connection->in_task_id, true); 716 716 if (!client) { … … 718 718 return 0; 719 719 } 720 720 721 721 fibril_connection->client = client; 722 722 723 723 /* 724 724 * Call the connection handler function. … … 726 726 fibril_connection->handler(fibril_connection->chandle, 727 727 &fibril_connection->call, fibril_connection->data); 728 728 729 729 /* 730 730 * Remove the reference for this client task connection. 731 731 */ 732 732 async_client_put(client); 733 733 734 734 /* 735 735 * Remove myself from the connection hash table. … … 741 741 }); 742 742 futex_up(&async_futex); 743 743 744 744 /* 745 745 * Answer all remaining messages with EHANGUP. … … 749 749 list_get_instance(list_first(&fibril_connection->msg_queue), 750 750 msg_t, link); 751 751 752 752 list_remove(&msg->link); 753 753 ipc_answer_0(msg->chandle, EHANGUP); 754 754 free(msg); 755 755 } 756 756 757 757 /* 758 758 * If the connection was hung-up, answer the last call, … … 761 761 if (fibril_connection->close_chandle) 762 762 ipc_answer_0(fibril_connection->close_chandle, EOK); 763 763 764 764 free(fibril_connection); 765 765 return EOK; … … 793 793 if (chandle != CAP_NIL) 794 794 ipc_answer_0(chandle, ENOMEM); 795 795 796 796 return (uintptr_t) NULL; 797 797 } 798 798 799 799 conn->in_task_id = in_task_id; 800 800 conn->in_phone_hash = in_phone_hash; … … 804 804 conn->handler = handler; 805 805 conn->data = data; 806 806 807 807 if (call) 808 808 conn->call = *call; 809 809 810 810 /* We will activate the fibril ASAP */ 811 811 conn->wdata.active = true; 812 812 conn->wdata.fid = fibril_create(connection_fibril, conn); 813 813 814 814 if (conn->wdata.fid == 0) { 815 815 free(conn); 816 816 817 817 if (chandle != CAP_NIL) 818 818 ipc_answer_0(chandle, ENOMEM); 819 819 820 820 return (uintptr_t) NULL; 821 821 } 822 822 823 823 /* Add connection to the connection hash table */ 824 824 825 825 futex_down(&async_futex); 826 826 hash_table_insert(&conn_hash_table, &conn->link); 827 827 futex_up(&async_futex); 828 828 829 829 fibril_add_ready(conn->wdata.fid); 830 830 831 831 return conn->wdata.fid; 832 832 } … … 852 852 if ((iface & IFACE_MOD_CALLBACK) != IFACE_MOD_CALLBACK) 853 853 return EINVAL; 854 854 855 855 if (exch == NULL) 856 856 return ENOENT; 857 857 858 858 ipc_call_t answer; 859 859 aid_t req = async_send_3(exch, IPC_M_CONNECT_TO_ME, iface, arg1, arg2, 860 860 &answer); 861 861 862 862 errno_t ret; 863 863 async_wait_for(req, &ret); 864 864 if (ret != EOK) 865 865 return (errno_t) ret; 866 866 867 867 sysarg_t phone_hash = IPC_GET_ARG5(answer); 868 868 interface_t *interface; 869 869 870 870 futex_down(&async_futex); 871 871 872 872 ht_link_t *link = hash_table_find(&interface_hash_table, &iface); 873 873 if (link) … … 875 875 else 876 876 interface = async_new_interface(iface); 877 877 878 878 if (!interface) { 879 879 futex_up(&async_futex); 880 880 return ENOMEM; 881 881 } 882 882 883 883 port_t *port = async_new_port(interface, handler, data); 884 884 if (!port) { … … 886 886 return ENOMEM; 887 887 } 888 888 889 889 *port_id = port->id; 890 890 891 891 futex_up(&async_futex); 892 892 893 893 fid_t fid = async_new_connection(answer.in_task_id, phone_hash, 894 894 CAP_NIL, NULL, handler, data); 895 895 if (fid == (uintptr_t) NULL) 896 896 return ENOMEM; 897 897 898 898 return EOK; 899 899 } … … 937 937 { 938 938 assert(wd); 939 939 940 940 wd->to_event.occurred = false; 941 941 wd->to_event.inlist = true; 942 942 943 943 link_t *tmp = timeout_list.head.next; 944 944 while (tmp != &timeout_list.head) { 945 945 awaiter_t *cur 946 946 = list_get_instance(tmp, awaiter_t, to_event.link); 947 947 948 948 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 949 949 break; 950 950 951 951 tmp = tmp->next; 952 952 } 953 953 954 954 list_insert_before(&wd->to_event.link, tmp); 955 955 } … … 971 971 { 972 972 assert(call); 973 973 974 974 futex_down(&async_futex); 975 975 976 976 ht_link_t *link = hash_table_find(&conn_hash_table, &(conn_key_t){ 977 977 .task_id = call->in_task_id, … … 982 982 return false; 983 983 } 984 984 985 985 connection_t *conn = hash_table_get_inst(link, connection_t, link); 986 986 987 987 msg_t *msg = malloc(sizeof(*msg)); 988 988 if (!msg) { … … 990 990 return false; 991 991 } 992 992 993 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 998 conn->close_chandle = chandle; 999 999 1000 1000 /* If the connection fibril is waiting for an event, activate it */ 1001 1001 if (!conn->wdata.active) { 1002 1002 1003 1003 /* If in timeout list, remove it */ 1004 1004 if (conn->wdata.to_event.inlist) { … … 1006 1006 list_remove(&conn->wdata.to_event.link); 1007 1007 } 1008 1008 1009 1009 conn->wdata.active = true; 1010 1010 fibril_add_ready(conn->wdata.fid); 1011 1011 } 1012 1012 1013 1013 futex_up(&async_futex); 1014 1014 return true; … … 1026 1026 1027 1027 assert(call); 1028 1028 1029 1029 futex_down(&async_futex); 1030 1030 1031 1031 ht_link_t *link = hash_table_find(¬ification_hash_table, 1032 1032 &IPC_GET_IMETHOD(*call)); … … 1037 1037 data = notification->data; 1038 1038 } 1039 1039 1040 1040 futex_up(&async_futex); 1041 1041 1042 1042 if (handler) 1043 1043 handler(call, data); … … 1063 1063 if (!notification) 1064 1064 return ENOMEM; 1065 1065 1066 1066 futex_down(&async_futex); 1067 1067 1068 1068 sysarg_t imethod = notification_avail; 1069 1069 notification_avail++; 1070 1070 1071 1071 notification->imethod = imethod; 1072 1072 notification->handler = handler; 1073 1073 notification->data = data; 1074 1074 1075 1075 hash_table_insert(¬ification_hash_table, ¬ification->link); 1076 1076 1077 1077 futex_up(&async_futex); 1078 1078 1079 1079 cap_handle_t cap; 1080 1080 errno_t rc = ipc_irq_subscribe(inr, imethod, ucode, &cap); … … 1096 1096 // TODO: Remove entry from hash table 1097 1097 // to avoid memory leak 1098 1098 1099 1099 return ipc_irq_unsubscribe(cap); 1100 1100 } … … 1116 1116 if (!notification) 1117 1117 return ENOMEM; 1118 1118 1119 1119 futex_down(&async_futex); 1120 1120 1121 1121 sysarg_t imethod = notification_avail; 1122 1122 notification_avail++; 1123 1123 1124 1124 notification->imethod = imethod; 1125 1125 notification->handler = handler; 1126 1126 notification->data = data; 1127 1127 1128 1128 hash_table_insert(¬ification_hash_table, ¬ification->link); 1129 1129 1130 1130 futex_up(&async_futex); 1131 1131 1132 1132 return ipc_event_subscribe(evno, imethod); 1133 1133 } … … 1149 1149 if (!notification) 1150 1150 return ENOMEM; 1151 1151 1152 1152 futex_down(&async_futex); 1153 1153 1154 1154 sysarg_t imethod = notification_avail; 1155 1155 notification_avail++; 1156 1156 1157 1157 notification->imethod = imethod; 1158 1158 notification->handler = handler; 1159 1159 notification->data = data; 1160 1160 1161 1161 hash_table_insert(¬ification_hash_table, ¬ification->link); 1162 1162 1163 1163 futex_up(&async_futex); 1164 1164 1165 1165 return ipc_event_task_subscribe(evno, imethod); 1166 1166 } … … 1204 1204 assert(call); 1205 1205 assert(fibril_connection); 1206 1206 1207 1207 /* Why doing this? 1208 1208 * GCC 4.1.0 coughs on fibril_connection-> dereference. … … 1212 1212 */ 1213 1213 connection_t *conn = fibril_connection; 1214 1214 1215 1215 futex_down(&async_futex); 1216 1216 1217 1217 if (usecs) { 1218 1218 getuptime(&conn->wdata.to_event.expires); … … 1220 1220 } else 1221 1221 conn->wdata.to_event.inlist = false; 1222 1222 1223 1223 /* If nothing in queue, wait until something arrives */ 1224 1224 while (list_empty(&conn->msg_queue)) { … … 1236 1236 return conn->close_chandle; 1237 1237 } 1238 1238 1239 1239 if (usecs) 1240 1240 async_insert_timeout(&conn->wdata); 1241 1241 1242 1242 conn->wdata.active = false; 1243 1243 1244 1244 /* 1245 1245 * Note: the current fibril will be rescheduled either due to a … … 1249 1249 */ 1250 1250 fibril_switch(FIBRIL_TO_MANAGER); 1251 1251 1252 1252 /* 1253 1253 * Futex is up after getting back from async_manager. … … 1262 1262 } 1263 1263 } 1264 1264 1265 1265 msg_t *msg = list_get_instance(list_first(&conn->msg_queue), 1266 1266 msg_t, link); 1267 1267 list_remove(&msg->link); 1268 1268 1269 1269 cap_handle_t chandle = msg->chandle; 1270 1270 *call = msg->call; 1271 1271 free(msg); 1272 1272 1273 1273 futex_up(&async_futex); 1274 1274 return chandle; … … 1286 1286 if (!client) 1287 1287 return NULL; 1288 1288 1289 1289 if (!client->data) { 1290 1290 async_client_put(client); 1291 1291 return NULL; 1292 1292 } 1293 1293 1294 1294 return client->data; 1295 1295 } … … 1298 1298 { 1299 1299 client_t *client = async_client_get(client_id, false); 1300 1300 1301 1301 assert(client); 1302 1302 assert(client->data); 1303 1303 1304 1304 /* Drop the reference we got in async_get_client_data_by_hash(). */ 1305 1305 async_client_put(client); 1306 1306 1307 1307 /* Drop our own reference we got at the beginning of this function. */ 1308 1308 async_client_put(client); … … 1312 1312 { 1313 1313 port_t *port = NULL; 1314 1314 1315 1315 futex_down(&async_futex); 1316 1316 1317 1317 ht_link_t *link = hash_table_find(&interface_hash_table, &iface); 1318 1318 if (link) { 1319 1319 interface_t *interface = 1320 1320 hash_table_get_inst(link, interface_t, link); 1321 1321 1322 1322 link = hash_table_find(&interface->port_hash_table, &port_id); 1323 1323 if (link) 1324 1324 port = hash_table_get_inst(link, port_t, link); 1325 1325 } 1326 1326 1327 1327 futex_up(&async_futex); 1328 1328 1329 1329 return port; 1330 1330 } … … 1342 1342 { 1343 1343 assert(call); 1344 1344 1345 1345 /* Kernel notification */ 1346 1346 if ((chandle == CAP_NIL) && (call->flags & IPC_CALL_NOTIF)) { 1347 1347 fibril_t *fibril = (fibril_t *) __tcb_get()->fibril_data; 1348 1348 unsigned oldsw = fibril->switches; 1349 1349 1350 1350 process_notification(call); 1351 1351 1352 1352 if (oldsw != fibril->switches) { 1353 1353 /* … … 1365 1365 fibril_switch(FIBRIL_FROM_DEAD); 1366 1366 } 1367 1367 1368 1368 return; 1369 1369 } 1370 1370 1371 1371 /* New connection */ 1372 1372 if (IPC_GET_IMETHOD(*call) == IPC_M_CONNECT_ME_TO) { 1373 1373 iface_t iface = (iface_t) IPC_GET_ARG1(*call); 1374 1374 sysarg_t in_phone_hash = IPC_GET_ARG5(*call); 1375 1375 1376 1376 async_port_handler_t handler = fallback_port_handler; 1377 1377 void *data = fallback_port_data; 1378 1378 1379 1379 // TODO: Currently ignores all ports but the first one 1380 1380 port_t *port = async_find_port(iface, 0); … … 1383 1383 data = port->data; 1384 1384 } 1385 1385 1386 1386 async_new_connection(call->in_task_id, in_phone_hash, chandle, 1387 1387 call, handler, data); 1388 1388 return; 1389 1389 } 1390 1390 1391 1391 /* Try to route the call through the connection hash table */ 1392 1392 if (route_call(chandle, call)) 1393 1393 return; 1394 1394 1395 1395 /* Unknown call from unknown phone - hang it up */ 1396 1396 ipc_answer_0(chandle, EHANGUP); … … 1402 1402 struct timeval tv; 1403 1403 getuptime(&tv); 1404 1404 1405 1405 futex_down(&async_futex); 1406 1406 1407 1407 link_t *cur = list_first(&timeout_list); 1408 1408 while (cur != NULL) { 1409 1409 awaiter_t *waiter = 1410 1410 list_get_instance(cur, awaiter_t, to_event.link); 1411 1411 1412 1412 if (tv_gt(&waiter->to_event.expires, &tv)) 1413 1413 break; 1414 1414 1415 1415 list_remove(&waiter->to_event.link); 1416 1416 waiter->to_event.inlist = false; 1417 1417 waiter->to_event.occurred = true; 1418 1418 1419 1419 /* 1420 1420 * Redundant condition? … … 1425 1425 fibril_add_ready(waiter->fid); 1426 1426 } 1427 1427 1428 1428 cur = list_first(&timeout_list); 1429 1429 } 1430 1430 1431 1431 futex_up(&async_futex); 1432 1432 } … … 1448 1448 continue; 1449 1449 } 1450 1450 1451 1451 futex_down(&async_futex); 1452 1452 1453 1453 suseconds_t timeout; 1454 1454 unsigned int flags = SYNCH_FLAGS_NONE; … … 1456 1456 awaiter_t *waiter = list_get_instance( 1457 1457 list_first(&timeout_list), awaiter_t, to_event.link); 1458 1458 1459 1459 struct timeval tv; 1460 1460 getuptime(&tv); 1461 1461 1462 1462 if (tv_gteq(&tv, &waiter->to_event.expires)) { 1463 1463 futex_up(&async_futex); … … 1485 1485 timeout = SYNCH_NO_TIMEOUT; 1486 1486 } 1487 1487 1488 1488 atomic_inc(&threads_in_ipc_wait); 1489 1489 1490 1490 ipc_call_t call; 1491 1491 errno_t rc = ipc_wait_cycle(&call, timeout, flags); 1492 1492 1493 1493 atomic_dec(&threads_in_ipc_wait); 1494 1494 1495 1495 assert(rc == EOK); 1496 1496 … … 1524 1524 { 1525 1525 futex_up(&async_futex); 1526 1526 1527 1527 /* 1528 1528 * async_futex is always locked when entering manager 1529 1529 */ 1530 1530 async_manager_worker(); 1531 1531 1532 1532 return 0; 1533 1533 } … … 1555 1555 &interface_hash_table_ops)) 1556 1556 abort(); 1557 1557 1558 1558 if (!hash_table_create(&client_hash_table, 0, 0, &client_hash_table_ops)) 1559 1559 abort(); 1560 1560 1561 1561 if (!hash_table_create(&conn_hash_table, 0, 0, &conn_hash_table_ops)) 1562 1562 abort(); 1563 1563 1564 1564 if (!hash_table_create(¬ification_hash_table, 0, 0, 1565 1565 ¬ification_hash_table_ops)) 1566 1566 abort(); 1567 1567 1568 1568 session_ns = (async_sess_t *) malloc(sizeof(async_sess_t)); 1569 1569 if (session_ns == NULL) 1570 1570 abort(); 1571 1571 1572 1572 session_ns->iface = 0; 1573 1573 session_ns->mgmt = EXCHANGE_ATOMIC; … … 1576 1576 session_ns->arg2 = 0; 1577 1577 session_ns->arg3 = 0; 1578 1578 1579 1579 fibril_mutex_initialize(&session_ns->remote_state_mtx); 1580 1580 session_ns->remote_state_data = NULL; 1581 1581 1582 1582 list_initialize(&session_ns->exch_list); 1583 1583 fibril_mutex_initialize(&session_ns->mutex); … … 1600 1600 { 1601 1601 assert(arg); 1602 1602 1603 1603 futex_down(&async_futex); 1604 1604 1605 1605 amsg_t *msg = (amsg_t *) arg; 1606 1606 msg->retval = retval; 1607 1607 1608 1608 /* Copy data after futex_down, just in case the call was detached */ 1609 1609 if ((msg->dataptr) && (data)) 1610 1610 *msg->dataptr = *data; 1611 1611 1612 1612 write_barrier(); 1613 1613 1614 1614 /* Remove message from timeout list */ 1615 1615 if (msg->wdata.to_event.inlist) 1616 1616 list_remove(&msg->wdata.to_event.link); 1617 1617 1618 1618 msg->done = true; 1619 1619 1620 1620 if (msg->forget) { 1621 1621 assert(msg->wdata.active); … … 1625 1625 fibril_add_ready(msg->wdata.fid); 1626 1626 } 1627 1627 1628 1628 futex_up(&async_futex); 1629 1629 } … … 1650 1650 if (exch == NULL) 1651 1651 return 0; 1652 1652 1653 1653 amsg_t *msg = amsg_create(); 1654 1654 if (msg == NULL) 1655 1655 return 0; 1656 1656 1657 1657 msg->dataptr = dataptr; 1658 1658 msg->wdata.active = true; 1659 1659 1660 1660 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg, 1661 1661 reply_received); 1662 1662 1663 1663 return (aid_t) msg; 1664 1664 } … … 1688 1688 if (exch == NULL) 1689 1689 return 0; 1690 1690 1691 1691 amsg_t *msg = amsg_create(); 1692 1692 if (msg == NULL) 1693 1693 return 0; 1694 1694 1695 1695 msg->dataptr = dataptr; 1696 1696 msg->wdata.active = true; 1697 1697 1698 1698 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5, 1699 1699 msg, reply_received); 1700 1700 1701 1701 return (aid_t) msg; 1702 1702 } … … 1712 1712 { 1713 1713 assert(amsgid); 1714 1714 1715 1715 amsg_t *msg = (amsg_t *) amsgid; 1716 1716 1717 1717 futex_down(&async_futex); 1718 1718 1719 1719 assert(!msg->forget); 1720 1720 assert(!msg->destroyed); 1721 1721 1722 1722 if (msg->done) { 1723 1723 futex_up(&async_futex); 1724 1724 goto done; 1725 1725 } 1726 1726 1727 1727 msg->wdata.fid = fibril_get_id(); 1728 1728 msg->wdata.active = false; 1729 1729 msg->wdata.to_event.inlist = false; 1730 1730 1731 1731 /* Leave the async_futex locked when entering this function */ 1732 1732 fibril_switch(FIBRIL_TO_MANAGER); 1733 1733 1734 1734 /* Futex is up automatically after fibril_switch */ 1735 1735 1736 1736 done: 1737 1737 if (retval) 1738 1738 *retval = msg->retval; 1739 1739 1740 1740 amsg_destroy(msg); 1741 1741 } … … 1758 1758 { 1759 1759 assert(amsgid); 1760 1760 1761 1761 amsg_t *msg = (amsg_t *) amsgid; 1762 1762 1763 1763 futex_down(&async_futex); 1764 1764 1765 1765 assert(!msg->forget); 1766 1766 assert(!msg->destroyed); 1767 1767 1768 1768 if (msg->done) { 1769 1769 futex_up(&async_futex); 1770 1770 goto done; 1771 1771 } 1772 1772 1773 1773 /* 1774 1774 * Negative timeout is converted to zero timeout to avoid … … 1777 1777 if (timeout < 0) 1778 1778 timeout = 0; 1779 1779 1780 1780 getuptime(&msg->wdata.to_event.expires); 1781 1781 tv_add_diff(&msg->wdata.to_event.expires, timeout); 1782 1782 1783 1783 /* 1784 1784 * Current fibril is inserted as waiting regardless of the … … 1801 1801 msg->wdata.active = false; 1802 1802 async_insert_timeout(&msg->wdata); 1803 1803 1804 1804 /* Leave the async_futex locked when entering this function */ 1805 1805 fibril_switch(FIBRIL_TO_MANAGER); 1806 1806 1807 1807 /* Futex is up automatically after fibril_switch */ 1808 1808 1809 1809 if (!msg->done) 1810 1810 return ETIMEOUT; 1811 1811 1812 1812 done: 1813 1813 if (retval) 1814 1814 *retval = msg->retval; 1815 1815 1816 1816 amsg_destroy(msg); 1817 1817 1818 1818 return 0; 1819 1819 } 1820 1820 1821 1821 /** Discard the message / reply on arrival. 1822 1822 * … … 1830 1830 { 1831 1831 amsg_t *msg = (amsg_t *) amsgid; 1832 1832 1833 1833 assert(msg); 1834 1834 assert(!msg->forget); 1835 1835 assert(!msg->destroyed); 1836 1836 1837 1837 futex_down(&async_futex); 1838 1838 1839 1839 if (msg->done) { 1840 1840 amsg_destroy(msg); … … 1843 1843 msg->forget = true; 1844 1844 } 1845 1845 1846 1846 futex_up(&async_futex); 1847 1847 } … … 1858 1858 awaiter_t awaiter; 1859 1859 awaiter_initialize(&awaiter); 1860 1860 1861 1861 awaiter.fid = fibril_get_id(); 1862 1862 1863 1863 getuptime(&awaiter.to_event.expires); 1864 1864 tv_add_diff(&awaiter.to_event.expires, timeout); 1865 1865 1866 1866 futex_down(&async_futex); 1867 1867 1868 1868 async_insert_timeout(&awaiter); 1869 1869 1870 1870 /* Leave the async_futex locked when entering this function */ 1871 1871 fibril_switch(FIBRIL_TO_MANAGER); 1872 1872 1873 1873 /* Futex is up automatically after fibril_switch() */ 1874 1874 } … … 1921 1921 if (exch == NULL) 1922 1922 return ENOENT; 1923 1923 1924 1924 ipc_call_t result; 1925 1925 aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4, 1926 1926 &result); 1927 1927 1928 1928 errno_t rc; 1929 1929 async_wait_for(aid, &rc); 1930 1930 1931 1931 if (r1) 1932 1932 *r1 = IPC_GET_ARG1(result); 1933 1933 1934 1934 if (r2) 1935 1935 *r2 = IPC_GET_ARG2(result); 1936 1936 1937 1937 if (r3) 1938 1938 *r3 = IPC_GET_ARG3(result); 1939 1939 1940 1940 if (r4) 1941 1941 *r4 = IPC_GET_ARG4(result); 1942 1942 1943 1943 if (r5) 1944 1944 *r5 = IPC_GET_ARG5(result); 1945 1945 1946 1946 return rc; 1947 1947 } … … 1973 1973 if (exch == NULL) 1974 1974 return ENOENT; 1975 1975 1976 1976 ipc_call_t result; 1977 1977 aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5, 1978 1978 &result); 1979 1979 1980 1980 errno_t rc; 1981 1981 async_wait_for(aid, &rc); 1982 1982 1983 1983 if (r1) 1984 1984 *r1 = IPC_GET_ARG1(result); 1985 1985 1986 1986 if (r2) 1987 1987 *r2 = IPC_GET_ARG2(result); 1988 1988 1989 1989 if (r3) 1990 1990 *r3 = IPC_GET_ARG3(result); 1991 1991 1992 1992 if (r4) 1993 1993 *r4 = IPC_GET_ARG4(result); 1994 1994 1995 1995 if (r5) 1996 1996 *r5 = IPC_GET_ARG5(result); 1997 1997 1998 1998 return rc; 1999 1999 } … … 2081 2081 if (exch == NULL) 2082 2082 return ENOENT; 2083 2083 2084 2084 return ipc_forward_fast(chandle, exch->phone, imethod, arg1, arg2, mode); 2085 2085 } … … 2091 2091 if (exch == NULL) 2092 2092 return ENOENT; 2093 2093 2094 2094 return ipc_forward_slow(chandle, exch->phone, imethod, arg1, arg2, arg3, 2095 2095 arg4, arg5, mode); … … 2113 2113 if (exch == NULL) 2114 2114 return ENOENT; 2115 2115 2116 2116 ipc_call_t answer; 2117 2117 aid_t req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 2118 2118 &answer); 2119 2119 2120 2120 errno_t rc; 2121 2121 async_wait_for(req, &rc); 2122 2122 if (rc != EOK) 2123 2123 return (errno_t) rc; 2124 2124 2125 2125 return EOK; 2126 2126 } … … 2130 2130 { 2131 2131 ipc_call_t result; 2132 2132 2133 2133 // XXX: Workaround for GCC's inability to infer association between 2134 2134 // rc == EOK and *out_phone being assigned. 2135 2135 *out_phone = -1; 2136 2136 2137 2137 amsg_t *msg = amsg_create(); 2138 2138 if (!msg) 2139 2139 return ENOENT; 2140 2140 2141 2141 msg->dataptr = &result; 2142 2142 msg->wdata.active = true; 2143 2143 2144 2144 ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4, 2145 2145 msg, reply_received); 2146 2146 2147 2147 errno_t rc; 2148 2148 async_wait_for((aid_t) msg, &rc); 2149 2149 2150 2150 if (rc != EOK) 2151 2151 return rc; 2152 2152 2153 2153 *out_phone = (int) IPC_GET_ARG5(result); 2154 2154 return EOK; … … 2175 2175 return NULL; 2176 2176 } 2177 2177 2178 2178 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2179 2179 if (sess == NULL) { … … 2181 2181 return NULL; 2182 2182 } 2183 2183 2184 2184 int phone; 2185 2185 errno_t rc = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, … … 2190 2190 return NULL; 2191 2191 } 2192 2192 2193 2193 sess->iface = 0; 2194 2194 sess->mgmt = mgmt; … … 2197 2197 sess->arg2 = arg2; 2198 2198 sess->arg3 = arg3; 2199 2199 2200 2200 fibril_mutex_initialize(&sess->remote_state_mtx); 2201 2201 sess->remote_state_data = NULL; 2202 2202 2203 2203 list_initialize(&sess->exch_list); 2204 2204 fibril_mutex_initialize(&sess->mutex); 2205 2205 atomic_set(&sess->refcnt, 0); 2206 2206 2207 2207 return sess; 2208 2208 } … … 2228 2228 return NULL; 2229 2229 } 2230 2230 2231 2231 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2232 2232 if (sess == NULL) { … … 2234 2234 return NULL; 2235 2235 } 2236 2236 2237 2237 int phone; 2238 2238 errno_t rc = async_connect_me_to_internal(exch->phone, iface, arg2, … … 2243 2243 return NULL; 2244 2244 } 2245 2245 2246 2246 sess->iface = iface; 2247 2247 sess->phone = phone; … … 2249 2249 sess->arg2 = arg2; 2250 2250 sess->arg3 = arg3; 2251 2251 2252 2252 fibril_mutex_initialize(&sess->remote_state_mtx); 2253 2253 sess->remote_state_data = NULL; 2254 2254 2255 2255 list_initialize(&sess->exch_list); 2256 2256 fibril_mutex_initialize(&sess->mutex); 2257 2257 atomic_set(&sess->refcnt, 0); 2258 2258 2259 2259 return sess; 2260 2260 } … … 2299 2299 return NULL; 2300 2300 } 2301 2301 2302 2302 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2303 2303 if (sess == NULL) { … … 2305 2305 return NULL; 2306 2306 } 2307 2307 2308 2308 int phone; 2309 2309 errno_t rc = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 2310 2310 IPC_FLAG_BLOCKING, &phone); 2311 2311 2312 2312 if (rc != EOK) { 2313 2313 errno = rc; … … 2315 2315 return NULL; 2316 2316 } 2317 2317 2318 2318 sess->iface = 0; 2319 2319 sess->mgmt = mgmt; … … 2322 2322 sess->arg2 = arg2; 2323 2323 sess->arg3 = arg3; 2324 2324 2325 2325 fibril_mutex_initialize(&sess->remote_state_mtx); 2326 2326 sess->remote_state_data = NULL; 2327 2327 2328 2328 list_initialize(&sess->exch_list); 2329 2329 fibril_mutex_initialize(&sess->mutex); 2330 2330 atomic_set(&sess->refcnt, 0); 2331 2331 2332 2332 return sess; 2333 2333 } … … 2353 2353 return NULL; 2354 2354 } 2355 2355 2356 2356 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2357 2357 if (sess == NULL) { … … 2359 2359 return NULL; 2360 2360 } 2361 2361 2362 2362 int phone; 2363 2363 errno_t rc = async_connect_me_to_internal(exch->phone, iface, arg2, … … 2368 2368 return NULL; 2369 2369 } 2370 2370 2371 2371 sess->iface = iface; 2372 2372 sess->phone = phone; … … 2374 2374 sess->arg2 = arg2; 2375 2375 sess->arg3 = arg3; 2376 2376 2377 2377 fibril_mutex_initialize(&sess->remote_state_mtx); 2378 2378 sess->remote_state_data = NULL; 2379 2379 2380 2380 list_initialize(&sess->exch_list); 2381 2381 fibril_mutex_initialize(&sess->mutex); 2382 2382 atomic_set(&sess->refcnt, 0); 2383 2383 2384 2384 return sess; 2385 2385 } … … 2395 2395 return NULL; 2396 2396 } 2397 2397 2398 2398 cap_handle_t phone; 2399 2399 errno_t rc = ipc_connect_kbox(id, &phone); … … 2403 2403 return NULL; 2404 2404 } 2405 2405 2406 2406 sess->iface = 0; 2407 2407 sess->mgmt = EXCHANGE_ATOMIC; … … 2410 2410 sess->arg2 = 0; 2411 2411 sess->arg3 = 0; 2412 2412 2413 2413 fibril_mutex_initialize(&sess->remote_state_mtx); 2414 2414 sess->remote_state_data = NULL; 2415 2415 2416 2416 list_initialize(&sess->exch_list); 2417 2417 fibril_mutex_initialize(&sess->mutex); 2418 2418 atomic_set(&sess->refcnt, 0); 2419 2419 2420 2420 return sess; 2421 2421 } … … 2436 2436 { 2437 2437 async_exch_t *exch; 2438 2438 2439 2439 assert(sess); 2440 2440 2441 2441 if (atomic_get(&sess->refcnt) > 0) 2442 2442 return EBUSY; 2443 2443 2444 2444 fibril_mutex_lock(&async_sess_mutex); 2445 2445 2446 2446 errno_t rc = async_hangup_internal(sess->phone); 2447 2447 2448 2448 while (!list_empty(&sess->exch_list)) { 2449 2449 exch = (async_exch_t *) 2450 2450 list_get_instance(list_first(&sess->exch_list), 2451 2451 async_exch_t, sess_link); 2452 2452 2453 2453 list_remove(&exch->sess_link); 2454 2454 list_remove(&exch->global_link); … … 2458 2458 2459 2459 free(sess); 2460 2460 2461 2461 fibril_mutex_unlock(&async_sess_mutex); 2462 2462 2463 2463 return rc; 2464 2464 } … … 2481 2481 if (sess == NULL) 2482 2482 return NULL; 2483 2483 2484 2484 exch_mgmt_t mgmt = sess->mgmt; 2485 2485 if (sess->iface != 0) 2486 2486 mgmt = sess->iface & IFACE_EXCHANGE_MASK; 2487 2487 2488 2488 async_exch_t *exch = NULL; 2489 2489 2490 2490 fibril_mutex_lock(&async_sess_mutex); 2491 2491 2492 2492 if (!list_empty(&sess->exch_list)) { 2493 2493 /* … … 2497 2497 list_get_instance(list_first(&sess->exch_list), 2498 2498 async_exch_t, sess_link); 2499 2499 2500 2500 list_remove(&exch->sess_link); 2501 2501 list_remove(&exch->global_link); … … 2504 2504 * There are no available exchanges in the session. 2505 2505 */ 2506 2506 2507 2507 if ((mgmt == EXCHANGE_ATOMIC) || 2508 2508 (mgmt == EXCHANGE_SERIALIZE)) { … … 2517 2517 int phone; 2518 2518 errno_t rc; 2519 2519 2520 2520 retry: 2521 2521 /* … … 2542 2542 list_get_instance(list_first(&inactive_exch_list), 2543 2543 async_exch_t, global_link); 2544 2544 2545 2545 list_remove(&exch->sess_link); 2546 2546 list_remove(&exch->global_link); … … 2557 2557 } 2558 2558 } 2559 2559 2560 2560 fibril_mutex_unlock(&async_sess_mutex); 2561 2561 2562 2562 if (exch != NULL) { 2563 2563 atomic_inc(&sess->refcnt); 2564 2564 2565 2565 if (mgmt == EXCHANGE_SERIALIZE) 2566 2566 fibril_mutex_lock(&sess->mutex); 2567 2567 } 2568 2568 2569 2569 return exch; 2570 2570 } … … 2579 2579 if (exch == NULL) 2580 2580 return; 2581 2581 2582 2582 async_sess_t *sess = exch->sess; 2583 2583 assert(sess != NULL); 2584 2584 2585 2585 exch_mgmt_t mgmt = sess->mgmt; 2586 2586 if (sess->iface != 0) 2587 2587 mgmt = sess->iface & IFACE_EXCHANGE_MASK; 2588 2588 2589 2589 atomic_dec(&sess->refcnt); 2590 2590 2591 2591 if (mgmt == EXCHANGE_SERIALIZE) 2592 2592 fibril_mutex_unlock(&sess->mutex); 2593 2593 2594 2594 fibril_mutex_lock(&async_sess_mutex); 2595 2595 2596 2596 list_append(&exch->sess_link, &sess->exch_list); 2597 2597 list_append(&exch->global_link, &inactive_exch_list); 2598 2598 fibril_condvar_signal(&avail_phone_cv); 2599 2599 2600 2600 fibril_mutex_unlock(&async_sess_mutex); 2601 2601 } … … 2618 2618 if (exch == NULL) 2619 2619 return ENOENT; 2620 2620 2621 2621 sysarg_t _flags = 0; 2622 2622 sysarg_t _dst = (sysarg_t) -1; 2623 2623 errno_t res = async_req_2_4(exch, IPC_M_SHARE_IN, (sysarg_t) size, 2624 2624 arg, NULL, &_flags, NULL, &_dst); 2625 2625 2626 2626 if (flags) 2627 2627 *flags = (unsigned int) _flags; 2628 2628 2629 2629 *dst = (void *) _dst; 2630 2630 return res; … … 2649 2649 assert(chandle); 2650 2650 assert(size); 2651 2651 2652 2652 ipc_call_t data; 2653 2653 *chandle = async_get_call(&data); 2654 2654 2655 2655 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN) 2656 2656 return false; 2657 2657 2658 2658 *size = (size_t) IPC_GET_ARG1(data); 2659 2659 return true; … … 2692 2692 if (exch == NULL) 2693 2693 return ENOENT; 2694 2694 2695 2695 return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 2696 2696 (sysarg_t) flags); … … 2718 2718 assert(size); 2719 2719 assert(flags); 2720 2720 2721 2721 ipc_call_t data; 2722 2722 *chandle = async_get_call(&data); 2723 2723 2724 2724 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT) 2725 2725 return false; 2726 2726 2727 2727 *size = (size_t) IPC_GET_ARG2(data); 2728 2728 *flags = (unsigned int) IPC_GET_ARG3(data); … … 2778 2778 if (exch == NULL) 2779 2779 return ENOENT; 2780 2780 2781 2781 return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst, 2782 2782 (sysarg_t) size); … … 2822 2822 assert(chandle); 2823 2823 assert(data); 2824 2824 2825 2825 *chandle = async_get_call(data); 2826 2826 2827 2827 if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_READ) 2828 2828 return false; 2829 2829 2830 2830 if (size) 2831 2831 *size = (size_t) IPC_GET_ARG2(*data); 2832 2832 2833 2833 return true; 2834 2834 } … … 2862 2862 if (exch == NULL) 2863 2863 return ENOENT; 2864 2864 2865 2865 cap_handle_t chandle; 2866 2866 if (!async_data_read_receive(&chandle, NULL)) { … … 2868 2868 return EINVAL; 2869 2869 } 2870 2870 2871 2871 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 2872 2872 dataptr); … … 2875 2875 return EINVAL; 2876 2876 } 2877 2877 2878 2878 errno_t retval = ipc_forward_fast(chandle, exch->phone, 0, 0, 0, 2879 2879 IPC_FF_ROUTE_FROM_ME); … … 2883 2883 return retval; 2884 2884 } 2885 2885 2886 2886 errno_t rc; 2887 2887 async_wait_for(msg, &rc); 2888 2888 2889 2889 return (errno_t) rc; 2890 2890 } … … 2903 2903 if (exch == NULL) 2904 2904 return ENOENT; 2905 2905 2906 2906 return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src, 2907 2907 (sysarg_t) size); … … 2948 2948 assert(chandle); 2949 2949 assert(data); 2950 2950 2951 2951 *chandle = async_get_call(data); 2952 2952 2953 2953 if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_WRITE) 2954 2954 return false; 2955 2955 2956 2956 if (size) 2957 2957 *size = (size_t) IPC_GET_ARG2(*data); 2958 2958 2959 2959 return true; 2960 2960 } … … 3004 3004 { 3005 3005 assert(data); 3006 3006 3007 3007 cap_handle_t chandle; 3008 3008 size_t size; … … 3011 3011 return EINVAL; 3012 3012 } 3013 3013 3014 3014 if (size < min_size) { 3015 3015 ipc_answer_0(chandle, EINVAL); 3016 3016 return EINVAL; 3017 3017 } 3018 3018 3019 3019 if ((max_size > 0) && (size > max_size)) { 3020 3020 ipc_answer_0(chandle, EINVAL); 3021 3021 return EINVAL; 3022 3022 } 3023 3023 3024 3024 if ((granularity > 0) && ((size % granularity) != 0)) { 3025 3025 ipc_answer_0(chandle, EINVAL); 3026 3026 return EINVAL; 3027 3027 } 3028 3028 3029 3029 void *arg_data; 3030 3030 3031 3031 if (nullterm) 3032 3032 arg_data = malloc(size + 1); 3033 3033 else 3034 3034 arg_data = malloc(size); 3035 3035 3036 3036 if (arg_data == NULL) { 3037 3037 ipc_answer_0(chandle, ENOMEM); 3038 3038 return ENOMEM; 3039 3039 } 3040 3040 3041 3041 errno_t rc = async_data_write_finalize(chandle, arg_data, size); 3042 3042 if (rc != EOK) { … … 3044 3044 return rc; 3045 3045 } 3046 3046 3047 3047 if (nullterm) 3048 3048 ((char *) arg_data)[size] = 0; 3049 3049 3050 3050 *data = arg_data; 3051 3051 if (received != NULL) 3052 3052 *received = size; 3053 3053 3054 3054 return EOK; 3055 3055 } … … 3078 3078 if (exch == NULL) 3079 3079 return ENOENT; 3080 3080 3081 3081 cap_handle_t chandle; 3082 3082 if (!async_data_write_receive(&chandle, NULL)) { … … 3084 3084 return EINVAL; 3085 3085 } 3086 3086 3087 3087 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 3088 3088 dataptr); … … 3091 3091 return EINVAL; 3092 3092 } 3093 3093 3094 3094 errno_t retval = ipc_forward_fast(chandle, exch->phone, 0, 0, 0, 3095 3095 IPC_FF_ROUTE_FROM_ME); … … 3099 3099 return retval; 3100 3100 } 3101 3101 3102 3102 errno_t rc; 3103 3103 async_wait_for(msg, &rc); 3104 3104 3105 3105 return (errno_t) rc; 3106 3106 } … … 3123 3123 cap_handle_t chandle = async_get_call(&call); 3124 3124 cap_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call); 3125 3125 3126 3126 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) || (phandle < 0)) { 3127 3127 async_answer_0(chandle, EINVAL); 3128 3128 return NULL; 3129 3129 } 3130 3130 3131 3131 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 3132 3132 if (sess == NULL) { … … 3134 3134 return NULL; 3135 3135 } 3136 3136 3137 3137 sess->iface = 0; 3138 3138 sess->mgmt = mgmt; … … 3141 3141 sess->arg2 = 0; 3142 3142 sess->arg3 = 0; 3143 3143 3144 3144 fibril_mutex_initialize(&sess->remote_state_mtx); 3145 3145 sess->remote_state_data = NULL; 3146 3146 3147 3147 list_initialize(&sess->exch_list); 3148 3148 fibril_mutex_initialize(&sess->mutex); 3149 3149 atomic_set(&sess->refcnt, 0); 3150 3150 3151 3151 /* Acknowledge the connected phone */ 3152 3152 async_answer_0(chandle, EOK); 3153 3153 3154 3154 return sess; 3155 3155 } … … 3172 3172 { 3173 3173 cap_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*call); 3174 3174 3175 3175 if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) || (phandle < 0)) 3176 3176 return NULL; 3177 3177 3178 3178 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 3179 3179 if (sess == NULL) 3180 3180 return NULL; 3181 3181 3182 3182 sess->iface = 0; 3183 3183 sess->mgmt = mgmt; … … 3186 3186 sess->arg2 = 0; 3187 3187 sess->arg3 = 0; 3188 3188 3189 3189 fibril_mutex_initialize(&sess->remote_state_mtx); 3190 3190 sess->remote_state_data = NULL; 3191 3191 3192 3192 list_initialize(&sess->exch_list); 3193 3193 fibril_mutex_initialize(&sess->mutex); 3194 3194 atomic_set(&sess->refcnt, 0); 3195 3195 3196 3196 return sess; 3197 3197 } … … 3208 3208 { 3209 3209 assert(chandle); 3210 3210 3211 3211 ipc_call_t call; 3212 3212 *chandle = async_get_call(&call); 3213 3213 3214 3214 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE) 3215 3215 return false; 3216 3216 3217 3217 if (arg1) 3218 3218 *arg1 = IPC_GET_ARG1(call); … … 3221 3221 if (arg3) 3222 3222 *arg3 = IPC_GET_ARG3(call); 3223 3223 3224 3224 return true; 3225 3225 } … … 3274 3274 { 3275 3275 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 3276 3276 3277 3277 fibril_mutex_unlock(&sess->remote_state_mtx); 3278 3278 } … … 3292 3292 if (exch == NULL) 3293 3293 return; 3294 3294 3295 3295 async_sess_t *sess = exch->sess; 3296 3296 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 3297 3297 3298 3298 async_exchange_end(exch); 3299 3299 fibril_mutex_unlock(&sess->remote_state_mtx);
Note:
See TracChangeset
for help on using the changeset viewer.