Changes in uspace/lib/c/generic/async.c [47b7006:23882034] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r47b7006 r23882034 43 43 * framework will automatically take care of most synchronization problems. 44 44 * 45 * Default semantics: 46 * - async_send_*(): Send asynchronously. If the kernel refuses to send 47 * more messages, [ try to get responses from kernel, if 48 * nothing found, might try synchronous ] 49 * 45 50 * Example of use (pseudo C): 46 51 * … … 53 58 * int fibril1(void *arg) 54 59 * { 55 * conn = async_connect_me_to();60 * conn = ipc_connect_me_to(); 56 61 * c1 = async_send(conn); 57 62 * c2 = async_send(conn); … … 72 77 * { 73 78 * if (want_refuse) { 74 * async_answer_0(icallid, ELIMIT);79 * ipc_answer_0(icallid, ELIMIT); 75 80 * return; 76 81 * } 77 * async_answer_0(icallid, EOK);82 * ipc_answer_0(icallid, EOK); 78 83 * 79 84 * callid = async_get_call(&call); 80 85 * somehow_handle_the_call(callid, call); 81 * async_answer_2(callid, 1, 2, 3);86 * ipc_answer_2(callid, 1, 2, 3); 82 87 * 83 88 * callid = async_get_call(&call); … … 87 92 */ 88 93 89 #define LIBC_ASYNC_C_ 90 #include <ipc/ipc.h> 94 #include <futex.h> 91 95 #include <async.h> 92 #undef LIBC_ASYNC_C_ 93 94 #include <futex.h> 96 #include <async_priv.h> 95 97 #include <fibril.h> 96 98 #include <stdio.h> 97 99 #include <adt/hash_table.h> 98 100 #include <adt/list.h> 101 #include <ipc/ipc.h> 99 102 #include <assert.h> 100 103 #include <errno.h> … … 102 105 #include <arch/barrier.h> 103 106 #include <bool.h> 104 #include "private/async.h"105 107 106 108 atomic_t async_futex = FUTEX_INITIALIZER; … … 122 124 123 125 /** 124 * Structures of this type are used to group information about 125 * a call and about amessage queue link.126 * Structures of this type are used to group information about a call and a 127 * message queue link. 126 128 */ 127 129 typedef struct { … … 151 153 /** Link to the client tracking structure. */ 152 154 client_t *client; 153 155 154 156 /** Messages that should be delivered to this fibril. */ 155 157 link_t msg_queue; … … 168 170 169 171 /** Identifier of the incoming connection handled by the current fibril. */ 170 staticfibril_local connection_t *FIBRIL_connection;172 fibril_local connection_t *FIBRIL_connection; 171 173 172 174 static void *default_client_data_constructor(void) … … 197 199 { 198 200 assert(FIBRIL_connection); 201 199 202 return FIBRIL_connection->client->data; 200 203 } 201 204 202 /** Default fibril function that gets called to handle new connection. 203 * 204 * This function is defined as a weak symbol - to be redefined in user code. 205 * 206 * @param callid Hash of the incoming call. 207 * @param call Data of the incoming call. 208 * 209 */ 210 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 211 { 212 ipc_answer_0(callid, ENOENT); 213 } 205 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); 206 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); 214 207 215 208 /** … … 217 210 */ 218 211 static async_client_conn_t client_connection = default_client_connection; 219 220 /** Default fibril function that gets called to handle interrupt notifications.221 *222 * This function is defined as a weak symbol - to be redefined in user code.223 *224 * @param callid Hash of the incoming call.225 * @param call Data of the incoming call.226 *227 */228 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)229 {230 }231 212 232 213 /** … … 240 221 static LIST_INITIALIZE(timeout_list); 241 222 242 #define CLIENT_HASH_TABLE_BUCKETS 243 #define CONN_HASH_TABLE_BUCKETS 244 245 static hash_index_t client_hash(unsigned long key[])223 #define CLIENT_HASH_TABLE_BUCKETS 32 224 #define CONN_HASH_TABLE_BUCKETS 32 225 226 static hash_index_t client_hash(unsigned long *key) 246 227 { 247 228 assert(key); 248 return ((( key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);229 return (((*key) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 249 230 } 250 231 251 232 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 252 233 { 253 client_t *cl ient= hash_table_get_instance(item, client_t, link);254 return (key[0] == cl ient->in_task_hash);234 client_t *cl = hash_table_get_instance(item, client_t, link); 235 return (key[0] == cl->in_task_hash); 255 236 } 256 237 … … 273 254 * 274 255 */ 275 static hash_index_t conn_hash(unsigned long key[])256 static hash_index_t conn_hash(unsigned long *key) 276 257 { 277 258 assert(key); 278 return ((( key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);259 return (((*key) >> 4) % CONN_HASH_TABLE_BUCKETS); 279 260 } 280 261 … … 290 271 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 291 272 { 292 connection_t * conn= hash_table_get_instance(item, connection_t, link);293 return (key[0] == conn->in_phone_hash);273 connection_t *hs = hash_table_get_instance(item, connection_t, link); 274 return (key[0] == hs->in_phone_hash); 294 275 } 295 276 … … 306 287 free(hash_table_get_instance(item, connection_t, link)); 307 288 } 289 308 290 309 291 /** Operations for the connection hash table. */ … … 326 308 link_t *tmp = timeout_list.next; 327 309 while (tmp != &timeout_list) { 328 awaiter_t *cur 329 = list_get_instance(tmp, awaiter_t, to_event.link); 310 awaiter_t *cur; 330 311 312 cur = list_get_instance(tmp, awaiter_t, to_event.link); 331 313 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 332 314 break; 333 334 315 tmp = tmp->next; 335 316 } … … 348 329 * 349 330 * @return False if the call doesn't match any connection. 350 * @returnTrue if the call was passed to the respective connection fibril.331 * True if the call was passed to the respective connection fibril. 351 332 * 352 333 */ … … 485 466 * the first IPC_M_PHONE_HUNGUP call and continues to 486 467 * call async_get_call_timeout(). Repeat 487 * IPC_M_PHONE_HUNGUP until the caller notices. 468 * IPC_M_PHONE_HUNGUP until the caller notices. 488 469 */ 489 470 memset(call, 0, sizeof(ipc_call_t)); … … 492 473 return conn->close_callid; 493 474 } 494 475 495 476 if (usecs) 496 477 async_insert_timeout(&conn->wdata); … … 530 511 } 531 512 513 /** Default fibril function that gets called to handle new connection. 514 * 515 * This function is defined as a weak symbol - to be redefined in user code. 516 * 517 * @param callid Hash of the incoming call. 518 * @param call Data of the incoming call. 519 * 520 */ 521 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 522 { 523 ipc_answer_0(callid, ENOENT); 524 } 525 526 /** Default fibril function that gets called to handle interrupt notifications. 527 * 528 * This function is defined as a weak symbol - to be redefined in user code. 529 * 530 * @param callid Hash of the incoming call. 531 * @param call Data of the incoming call. 532 * 533 */ 534 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call) 535 { 536 } 537 532 538 /** Wrapper for client connection fibril. 533 539 * … … 542 548 static int connection_fibril(void *arg) 543 549 { 550 unsigned long key; 551 client_t *cl; 552 link_t *lnk; 553 bool destroy = false; 554 544 555 /* 545 556 * Setup fibril-local connection pointer. 546 557 */ 547 558 FIBRIL_connection = (connection_t *) arg; 548 549 futex_down(&async_futex); 550 559 551 560 /* 552 561 * Add our reference for the current connection in the client task … … 554 563 * hash in a new tracking structure. 555 564 */ 556 557 unsigned long key = FIBRIL_connection->in_task_hash; 558 link_t *lnk = hash_table_find(&client_hash_table, &key); 559 560 client_t *client; 561 565 futex_down(&async_futex); 566 key = FIBRIL_connection->in_task_hash; 567 lnk = hash_table_find(&client_hash_table, &key); 562 568 if (lnk) { 563 cl ient= hash_table_get_instance(lnk, client_t, link);564 cl ient->refcnt++;569 cl = hash_table_get_instance(lnk, client_t, link); 570 cl->refcnt++; 565 571 } else { 566 cl ient= malloc(sizeof(client_t));567 if (!cl ient) {572 cl = malloc(sizeof(client_t)); 573 if (!cl) { 568 574 ipc_answer_0(FIBRIL_connection->callid, ENOMEM); 569 575 futex_up(&async_futex); 570 576 return 0; 571 577 } 572 573 client->in_task_hash = FIBRIL_connection->in_task_hash; 574 578 cl->in_task_hash = FIBRIL_connection->in_task_hash; 575 579 async_serialize_start(); 576 cl ient->data = async_client_data_create();580 cl->data = async_client_data_create(); 577 581 async_serialize_end(); 578 579 client->refcnt = 1; 580 hash_table_insert(&client_hash_table, &key, &client->link); 581 } 582 582 cl->refcnt = 1; 583 hash_table_insert(&client_hash_table, &key, &cl->link); 584 } 583 585 futex_up(&async_futex); 584 585 FIBRIL_connection->client = cl ient;586 586 587 FIBRIL_connection->client = cl; 588 587 589 /* 588 590 * Call the connection handler function. … … 594 596 * Remove the reference for this client task connection. 595 597 */ 596 bool destroy;597 598 598 futex_down(&async_futex); 599 600 if (--client->refcnt == 0) { 599 if (--cl->refcnt == 0) { 601 600 hash_table_remove(&client_hash_table, &key, 1); 602 601 destroy = true; 603 } else 604 destroy = false; 605 602 } 606 603 futex_up(&async_futex); 607 604 608 605 if (destroy) { 609 if (client->data) 610 async_client_data_destroy(client->data); 611 612 free(client); 613 } 614 606 if (cl->data) 607 async_client_data_destroy(cl->data); 608 free(cl); 609 } 610 615 611 /* 616 612 * Remove myself from the connection hash table. … … 625 621 */ 626 622 while (!list_empty(&FIBRIL_connection->msg_queue)) { 627 msg_t *msg = 628 list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, 629 link); 623 msg_t *msg; 630 624 625 msg = list_get_instance(FIBRIL_connection->msg_queue.next, 626 msg_t, link); 631 627 list_remove(&msg->link); 632 628 ipc_answer_0(msg->callid, EHANGUP); … … 671 667 if (callid) 672 668 ipc_answer_0(callid, ENOMEM); 673 674 669 return (uintptr_t) NULL; 675 670 } … … 719 714 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 720 715 { 721 /* Unrouted call - take some default action*/716 /* Unrouted call - do some default behaviour */ 722 717 if ((callid & IPC_CALLID_NOTIFICATION)) { 723 718 process_notification(callid, call); 724 return;719 goto out; 725 720 } 726 721 … … 728 723 case IPC_M_CONNECT_ME: 729 724 case IPC_M_CONNECT_ME_TO: 730 /* Open new connection with fibril ,etc. */725 /* Open new connection with fibril etc. */ 731 726 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call), 732 727 callid, call, client_connection); 733 return;728 goto out; 734 729 } 735 730 736 731 /* Try to route the call through the connection hash table */ 737 732 if (route_call(callid, call)) 738 return;733 goto out; 739 734 740 735 /* Unknown call from unknown phone - hang it up */ 741 736 ipc_answer_0(callid, EHANGUP); 737 return; 738 739 out: 740 ; 742 741 } 743 742 … … 752 751 link_t *cur = timeout_list.next; 753 752 while (cur != &timeout_list) { 754 awaiter_t *waiter = 755 list_get_instance(cur, awaiter_t, to_event.link); 753 awaiter_t *waiter; 756 754 755 waiter = list_get_instance(cur, awaiter_t, to_event.link); 757 756 if (tv_gt(&waiter->to_event.expires, &tv)) 758 757 break; 759 758 760 759 cur = cur->next; 761 760 762 761 list_remove(&waiter->to_event.link); 763 762 waiter->to_event.inlist = false; … … 786 785 while (true) { 787 786 if (fibril_switch(FIBRIL_FROM_MANAGER)) { 788 futex_up(&async_futex); 787 futex_up(&async_futex); 789 788 /* 790 789 * async_futex is always held when entering a manager … … 809 808 continue; 810 809 } else 811 timeout = tv_sub(&waiter->to_event.expires, &tv); 810 timeout = tv_sub(&waiter->to_event.expires, 811 &tv); 812 812 } else 813 813 timeout = SYNCH_NO_TIMEOUT; 814 814 815 815 futex_up(&async_futex); 816 816 817 817 atomic_inc(&threads_in_ipc_wait); 818 818 … … 822 822 823 823 atomic_dec(&threads_in_ipc_wait); 824 824 825 825 if (!callid) { 826 826 handle_expired_timeouts(); … … 872 872 /** Initialize the async framework. 873 873 * 874 */ 875 void __async_init(void) 874 * @return Zero on success or an error code. 875 */ 876 int __async_init(void) 876 877 { 877 878 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1, 878 &client_hash_table_ops)) 879 abort(); 880 881 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1, 882 &conn_hash_table_ops)) 883 abort(); 879 &client_hash_table_ops) || !hash_table_create(&conn_hash_table, 880 CONN_HASH_TABLE_BUCKETS, 1, &conn_hash_table_ops)) { 881 return ENOMEM; 882 } 883 884 _async_sess_init(); 885 886 return 0; 884 887 } 885 888 … … 894 897 * @param retval Value returned in the answer. 895 898 * @param data Call data of the answer. 896 *897 899 */ 898 900 static void reply_received(void *arg, int retval, ipc_call_t *data) … … 942 944 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 943 945 { 944 amsg_t *msg = malloc(sizeof( amsg_t));946 amsg_t *msg = malloc(sizeof(*msg)); 945 947 946 948 if (!msg) … … 951 953 952 954 msg->wdata.to_event.inlist = false; 953 954 /* 955 * We may sleep in the next method, 956 * but it will use its own means 957 */ 955 /* We may sleep in the next method, but it will use its own mechanism */ 958 956 msg->wdata.active = true; 959 957 … … 986 984 ipc_call_t *dataptr) 987 985 { 988 amsg_t *msg = malloc(sizeof( amsg_t));986 amsg_t *msg = malloc(sizeof(*msg)); 989 987 990 988 if (!msg) … … 995 993 996 994 msg->wdata.to_event.inlist = false; 997 998 /* 999 * We may sleep in the next method, 1000 * but it will use its own means 1001 */ 995 /* We may sleep in next method, but it will use its own mechanism */ 1002 996 msg->wdata.active = true; 1003 997 … … 1098 1092 void async_usleep(suseconds_t timeout) 1099 1093 { 1100 amsg_t *msg = malloc(sizeof( amsg_t));1094 amsg_t *msg = malloc(sizeof(*msg)); 1101 1095 1102 1096 if (!msg) … … 1241 1235 } 1242 1236 1243 void async_msg_0(int phone, sysarg_t imethod) 1244 { 1245 ipc_call_async_0(phone, imethod, NULL, NULL, true); 1246 } 1247 1248 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1) 1249 { 1250 ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true); 1251 } 1252 1253 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2) 1254 { 1255 ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true); 1256 } 1257 1258 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1259 sysarg_t arg3) 1260 { 1261 ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true); 1262 } 1263 1264 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1265 sysarg_t arg3, sysarg_t arg4) 1266 { 1267 ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL, 1268 true); 1269 } 1270 1271 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1272 sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1273 { 1274 ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL, 1275 NULL, true); 1276 } 1277 1278 sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval) 1279 { 1280 return ipc_answer_0(callid, retval); 1281 } 1282 1283 sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1) 1284 { 1285 return ipc_answer_1(callid, retval, arg1); 1286 } 1287 1288 sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, 1289 sysarg_t arg2) 1290 { 1291 return ipc_answer_2(callid, retval, arg1, arg2); 1292 } 1293 1294 sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, 1295 sysarg_t arg2, sysarg_t arg3) 1296 { 1297 return ipc_answer_3(callid, retval, arg1, arg2, arg3); 1298 } 1299 1300 sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, 1301 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 1302 { 1303 return ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4); 1304 } 1305 1306 sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1, 1307 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1308 { 1309 return ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5); 1310 } 1311 1312 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1313 sysarg_t arg1, sysarg_t arg2, unsigned int mode) 1314 { 1315 return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode); 1316 } 1317 1318 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1319 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 1320 unsigned int mode) 1321 { 1322 return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4, 1323 arg5, mode); 1324 } 1325 1326 /** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework. 1327 * 1237 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1238 * 1328 1239 * Ask through phone for a new connection to some service. 1329 1240 * 1330 * @param phone 1331 * @param arg1 1332 * @param arg2 1333 * @param arg3 1334 * @param client_receiver Connection handing routine.1335 * 1336 * @return New phone handle on success or a negative error code.1337 * 1338 */ 1339 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2, 1340 sysarg_t arg3, async_client_conn_t client_receiver) 1341 { 1342 sysarg_t task_hash; 1343 sysarg_t phone_hash;1344 int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,1345 NULL, NULL, NULL, &task_hash, &phone_hash);1346 if (rc != EOK) 1241 * @param phoneid Phone handle used for contacting the other side. 1242 * @param arg1 User defined argument. 1243 * @param arg2 User defined argument. 1244 * @param arg3 User defined argument. 1245 * 1246 * @return New phone handle on success or a negative error code. 1247 */ 1248 int 1249 async_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 1250 { 1251 int rc; 1252 sysarg_t newphid; 1253 1254 rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL, 1255 NULL, NULL, NULL, &newphid); 1256 1257 if (rc != EOK) 1347 1258 return rc; 1348 1349 if (client_receiver != NULL) 1350 async_new_connection(task_hash, phone_hash, 0, NULL, 1351 client_receiver); 1352 1353 return EOK; 1259 1260 return newphid; 1354 1261 } 1355 1262 1356 1263 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1357 * 1358 * Ask through phone for a new connection to some service. 1359 * 1360 * @param phone Phone handle used for contacting the other side. 1361 * @param arg1 User defined argument. 1362 * @param arg2 User defined argument. 1363 * @param arg3 User defined argument. 1364 * 1365 * @return New phone handle on success or a negative error code. 1366 * 1367 */ 1368 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2, 1369 sysarg_t arg3) 1370 { 1371 sysarg_t newphid; 1372 int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1373 NULL, NULL, NULL, NULL, &newphid); 1374 1375 if (rc != EOK) 1376 return rc; 1377 1378 return newphid; 1379 } 1380 1381 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1382 * 1264 * 1383 1265 * Ask through phone for a new connection to some service and block until 1384 1266 * success. 1385 1267 * 1386 * @param phoneid 1387 * @param arg1 1388 * @param arg2 1389 * @param arg3 1390 * 1391 * @return 1392 * 1393 */ 1394 intasync_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,1268 * @param phoneid Phone handle used for contacting the other side. 1269 * @param arg1 User defined argument. 1270 * @param arg2 User defined argument. 1271 * @param arg3 User defined argument. 1272 * 1273 * @return New phone handle on success or a negative error code. 1274 */ 1275 int 1276 async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2, 1395 1277 sysarg_t arg3) 1396 1278 { 1279 int rc; 1397 1280 sysarg_t newphid; 1398 int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1281 1282 rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1399 1283 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); 1400 1284 1401 if (rc != EOK) 1285 if (rc != EOK) 1402 1286 return rc; 1403 1287 1404 1288 return newphid; 1405 1289 } 1406 1290 1407 /** Connect to a task specified by id. 1408 * 1409 */ 1410 int async_connect_kbox(task_id_t id) 1411 { 1412 return ipc_connect_kbox(id); 1413 } 1414 1415 /** Wrapper for ipc_hangup. 1416 * 1417 * @param phone Phone handle to hung up. 1418 * 1419 * @return Zero on success or a negative error code. 1420 * 1421 */ 1422 int async_hangup(int phone) 1423 { 1424 return ipc_hangup(phone); 1425 } 1426 1427 /** Interrupt one thread of this task from waiting for IPC. */ 1428 void async_poke(void) 1429 { 1430 ipc_poke(); 1431 } 1432 1433 /** Wrapper for IPC_M_SHARE_IN calls using the async framework. 1434 * 1435 * @param phoneid Phone that will be used to contact the receiving side. 1436 * @param dst Destination address space area base. 1437 * @param size Size of the destination address space area. 1438 * @param arg User defined argument. 1439 * @param flags Storage for the received flags. Can be NULL. 1440 * 1441 * @return Zero on success or a negative error code from errno.h. 1442 * 1291 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework. 1292 * 1293 * @param phoneid Phone that will be used to contact the receiving side. 1294 * @param dst Destination address space area base. 1295 * @param size Size of the destination address space area. 1296 * @param arg User defined argument. 1297 * @param flags Storage where the received flags will be stored. Can be 1298 * NULL. 1299 * 1300 * @return Zero on success or a negative error code from errno.h. 1443 1301 */ 1444 1302 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 1445 unsigned int *flags) 1446 { 1303 int *flags) 1304 { 1305 int res; 1447 1306 sysarg_t tmp_flags; 1448 intres = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,1307 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst, 1449 1308 (sysarg_t) size, arg, NULL, &tmp_flags); 1450 1451 1309 if (flags) 1452 *flags = (unsigned int) tmp_flags; 1453 1310 *flags = tmp_flags; 1454 1311 return res; 1455 1312 } … … 1457 1314 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework. 1458 1315 * 1459 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN 1460 * calls so that the user doesn't have to remember the meaning of each IPC 1461 * argument. 1316 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls 1317 * so that the user doesn't have to remember the meaning of each IPC argument. 1462 1318 * 1463 1319 * So far, this wrapper is to be used from within a connection fibril. 1464 1320 * 1465 * @param callid Storage for the hash of the IPC_M_SHARE_IN call. 1466 * @param size Destination address space area size. 1467 * 1468 * @return True on success, false on failure. 1469 * 1470 */ 1471 bool async_share_in_receive(ipc_callid_t *callid, size_t *size) 1472 { 1321 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will 1322 * be stored. 1323 * @param size Destination address space area size. 1324 * 1325 * @return Non-zero on success, zero on failure. 1326 */ 1327 int async_share_in_receive(ipc_callid_t *callid, size_t *size) 1328 { 1329 ipc_call_t data; 1330 1473 1331 assert(callid); 1474 1332 assert(size); 1475 1476 ipc_call_t data; 1333 1477 1334 *callid = async_get_call(&data); 1478 1479 1335 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN) 1480 return false; 1481 1336 return 0; 1482 1337 *size = (size_t) IPC_GET_ARG2(data); 1483 return true;1338 return 1; 1484 1339 } 1485 1340 1486 1341 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework. 1487 1342 * 1488 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 1489 * calls so that the user doesn't have to remember the meaning of each IPC 1490 * argument. 1491 * 1492 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1493 * @param src Source address space base. 1494 * @param flags Flags to be used for sharing. Bits can be only cleared. 1495 * 1496 * @return Zero on success or a value from @ref errno.h on failure. 1497 * 1498 */ 1499 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 1343 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1344 * so that the user doesn't have to remember the meaning of each IPC argument. 1345 * 1346 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1347 * @param src Source address space base. 1348 * @param flags Flags to be used for sharing. Bits can be only cleared. 1349 * 1350 * @return Zero on success or a value from @ref errno.h on failure. 1351 */ 1352 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags) 1500 1353 { 1501 1354 return ipc_share_in_finalize(callid, src, flags); 1502 1355 } 1503 1356 1504 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework. 1505 * 1506 * @param phoneid Phone that will be used to contact the receiving side. 1507 * @param src Source address space area base address. 1508 * @param flags Flags to be used for sharing. Bits can be only cleared. 1509 * 1510 * @return Zero on success or a negative error code from errno.h. 1511 * 1512 */ 1513 int async_share_out_start(int phoneid, void *src, unsigned int flags) 1357 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework. 1358 * 1359 * @param phoneid Phone that will be used to contact the receiving side. 1360 * @param src Source address space area base address. 1361 * @param flags Flags to be used for sharing. Bits can be only cleared. 1362 * 1363 * @return Zero on success or a negative error code from errno.h. 1364 */ 1365 int async_share_out_start(int phoneid, void *src, int flags) 1514 1366 { 1515 1367 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, … … 1519 1371 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework. 1520 1372 * 1521 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT 1522 * calls so that the user doesn't have to remember the meaning of each IPC 1523 * argument. 1373 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls 1374 * so that the user doesn't have to remember the meaning of each IPC argument. 1524 1375 * 1525 1376 * So far, this wrapper is to be used from within a connection fibril. 1526 1377 * 1527 * @param callid Storage for the hash of the IPC_M_SHARE_OUT call. 1528 * @param size Storage for the source address space area size. 1529 * @param flags Storage for the sharing flags. 1530 * 1531 * @return True on success, false on failure. 1532 * 1533 */ 1534 bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags) 1535 { 1378 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will 1379 * be stored. 1380 * @param size Storage where the source address space area size will be 1381 * stored. 1382 * @param flags Storage where the sharing flags will be stored. 1383 * 1384 * @return Non-zero on success, zero on failure. 1385 */ 1386 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags) 1387 { 1388 ipc_call_t data; 1389 1536 1390 assert(callid); 1537 1391 assert(size); 1538 1392 assert(flags); 1539 1540 ipc_call_t data; 1393 1541 1394 *callid = async_get_call(&data); 1542 1543 1395 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT) 1544 return false; 1545 1396 return 0; 1546 1397 *size = (size_t) IPC_GET_ARG2(data); 1547 *flags = ( unsignedint) IPC_GET_ARG3(data);1548 return true;1398 *flags = (int) IPC_GET_ARG3(data); 1399 return 1; 1549 1400 } 1550 1401 1551 1402 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework. 1552 1403 * 1553 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT 1554 * calls so that the user doesn't have to remember the meaning of each IPC 1555 * argument. 1556 * 1557 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1558 * @param dst Destination address space area base address. 1559 * 1560 * @return Zero on success or a value from @ref errno.h on failure. 1561 * 1404 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 1405 * so that the user doesn't have to remember the meaning of each IPC argument. 1406 * 1407 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1408 * @param dst Destination address space area base address. 1409 * 1410 * @return Zero on success or a value from @ref errno.h on failure. 1562 1411 */ 1563 1412 int async_share_out_finalize(ipc_callid_t callid, void *dst) … … 1566 1415 } 1567 1416 1568 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1569 * 1570 * @param phoneid Phone that will be used to contact the receiving side.1571 * @param dst Address of the beginning of the destination buffer.1572 * @param size Sizeof the destination buffer.1573 * 1574 * @return Zero on success or a negative error code from errno.h.1575 * 1417 1418 /** Wrapper for making IPC_M_DATA_READ calls using the async framework. 1419 * 1420 * @param phoneid Phone that will be used to contact the receiving side. 1421 * @param dst Address of the beginning of the destination buffer. 1422 * @param size Size of the destination buffer. 1423 * 1424 * @return Zero on success or a negative error code from errno.h. 1576 1425 */ 1577 1426 int async_data_read_start(int phoneid, void *dst, size_t size) … … 1583 1432 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework. 1584 1433 * 1585 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ 1586 * calls so that the user doesn't have to remember the meaning of each IPC 1587 * argument. 1434 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 1435 * so that the user doesn't have to remember the meaning of each IPC argument. 1588 1436 * 1589 1437 * So far, this wrapper is to be used from within a connection fibril. 1590 1438 * 1591 * @param callid Storage for the hash of the IPC_M_DATA_READ. 1592 * @param size Storage for the maximum size. Can be NULL. 1593 * 1594 * @return True on success, false on failure. 1595 * 1596 */ 1597 bool async_data_read_receive(ipc_callid_t *callid, size_t *size) 1598 { 1439 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 1440 * be stored. 1441 * @param size Storage where the maximum size will be stored. Can be 1442 * NULL. 1443 * 1444 * @return Non-zero on success, zero on failure. 1445 */ 1446 int async_data_read_receive(ipc_callid_t *callid, size_t *size) 1447 { 1448 ipc_call_t data; 1449 1599 1450 assert(callid); 1600 1601 ipc_call_t data; 1451 1602 1452 *callid = async_get_call(&data); 1603 1604 1453 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ) 1605 return false; 1606 1454 return 0; 1607 1455 if (size) 1608 1456 *size = (size_t) IPC_GET_ARG2(data); 1609 1610 return true; 1457 return 1; 1611 1458 } 1612 1459 1613 1460 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework. 1614 1461 * 1615 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 1616 * calls so that the user doesn't have to remember the meaning of each IPC 1617 * argument. 1618 * 1619 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1620 * @param src Source address for the IPC_M_DATA_READ call. 1621 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1622 * the maximum size announced by the sender. 1623 * 1624 * @return Zero on success or a value from @ref errno.h on failure. 1625 * 1462 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1463 * so that the user doesn't have to remember the meaning of each IPC argument. 1464 * 1465 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1466 * @param src Source address for the IPC_M_DATA_READ call. 1467 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1468 * the maximum size announced by the sender. 1469 * 1470 * @return Zero on success or a value from @ref errno.h on failure. 1626 1471 */ 1627 1472 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) … … 1631 1476 1632 1477 /** Wrapper for forwarding any read request 1478 * 1633 1479 * 1634 1480 */ … … 1663 1509 } 1664 1510 1665 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.1511 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1666 1512 * 1667 1513 * @param phoneid Phone that will be used to contact the receiving side. … … 1680 1526 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework. 1681 1527 * 1682 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE 1683 * calls so that the user doesn't have to remember the meaning of each IPC 1684 * argument. 1528 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls 1529 * so that the user doesn't have to remember the meaning of each IPC argument. 1685 1530 * 1686 1531 * So far, this wrapper is to be used from within a connection fibril. 1687 1532 * 1688 * @param callid Storage for the hash of the IPC_M_DATA_WRITE. 1689 * @param size Storage for the suggested size. May be NULL. 1690 * 1691 * @return True on success, false on failure. 1692 * 1693 */ 1694 bool async_data_write_receive(ipc_callid_t *callid, size_t *size) 1695 { 1533 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1534 * be stored. 1535 * @param size Storage where the suggested size will be stored. May be 1536 * NULL 1537 * 1538 * @return Non-zero on success, zero on failure. 1539 * 1540 */ 1541 int async_data_write_receive(ipc_callid_t *callid, size_t *size) 1542 { 1543 ipc_call_t data; 1544 1696 1545 assert(callid); 1697 1546 1698 ipc_call_t data;1699 1547 *callid = async_get_call(&data); 1700 1701 1548 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE) 1702 return false;1549 return 0; 1703 1550 1704 1551 if (size) 1705 1552 *size = (size_t) IPC_GET_ARG2(data); 1706 1553 1707 return true;1554 return 1; 1708 1555 } 1709 1556 1710 1557 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework. 1711 1558 * 1712 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE 1713 * calls so that the user doesn't have to remember the meaning of each IPC 1714 * argument. 1559 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 1560 * so that the user doesn't have to remember the meaning of each IPC argument. 1715 1561 * 1716 1562 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. … … 1808 1654 * 1809 1655 */ 1810 void async_data_write_void( sysarg_t retval)1656 void async_data_write_void(const int retval) 1811 1657 { 1812 1658 ipc_callid_t callid; … … 1816 1662 1817 1663 /** Wrapper for forwarding any data that is about to be received 1664 * 1818 1665 * 1819 1666 */
Note:
See TracChangeset
for help on using the changeset viewer.