Changes in uspace/lib/c/generic/async.c [47b7006:64d2b10] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r47b7006 r64d2b10 42 42 * You should be able to write very simple multithreaded programs, the async 43 43 * framework will automatically take care of most synchronization problems. 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 ] 44 49 * 45 50 * Example of use (pseudo C): … … 122 127 123 128 /** 124 * Structures of this type are used to group information about 125 * a call and about amessage queue link.129 * Structures of this type are used to group information about a call and a 130 * message queue link. 126 131 */ 127 132 typedef struct { … … 151 156 /** Link to the client tracking structure. */ 152 157 client_t *client; 153 158 154 159 /** Messages that should be delivered to this fibril. */ 155 160 link_t msg_queue; … … 168 173 169 174 /** Identifier of the incoming connection handled by the current fibril. */ 170 staticfibril_local connection_t *FIBRIL_connection;175 fibril_local connection_t *FIBRIL_connection; 171 176 172 177 static void *default_client_data_constructor(void) … … 197 202 { 198 203 assert(FIBRIL_connection); 204 199 205 return FIBRIL_connection->client->data; 200 206 } 201 207 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 } 208 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); 209 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); 214 210 215 211 /** … … 217 213 */ 218 214 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 215 232 216 /** … … 240 224 static LIST_INITIALIZE(timeout_list); 241 225 242 #define CLIENT_HASH_TABLE_BUCKETS 243 #define CONN_HASH_TABLE_BUCKETS 244 245 static hash_index_t client_hash(unsigned long key[])226 #define CLIENT_HASH_TABLE_BUCKETS 32 227 #define CONN_HASH_TABLE_BUCKETS 32 228 229 static hash_index_t client_hash(unsigned long *key) 246 230 { 247 231 assert(key); 248 return ((( key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);232 return (((*key) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 249 233 } 250 234 251 235 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 252 236 { 253 client_t *cl ient= hash_table_get_instance(item, client_t, link);254 return (key[0] == cl ient->in_task_hash);237 client_t *cl = hash_table_get_instance(item, client_t, link); 238 return (key[0] == cl->in_task_hash); 255 239 } 256 240 … … 273 257 * 274 258 */ 275 static hash_index_t conn_hash(unsigned long key[])259 static hash_index_t conn_hash(unsigned long *key) 276 260 { 277 261 assert(key); 278 return ((( key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);262 return (((*key) >> 4) % CONN_HASH_TABLE_BUCKETS); 279 263 } 280 264 … … 290 274 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 291 275 { 292 connection_t * conn= hash_table_get_instance(item, connection_t, link);293 return (key[0] == conn->in_phone_hash);276 connection_t *hs = hash_table_get_instance(item, connection_t, link); 277 return (key[0] == hs->in_phone_hash); 294 278 } 295 279 … … 306 290 free(hash_table_get_instance(item, connection_t, link)); 307 291 } 292 308 293 309 294 /** Operations for the connection hash table. */ … … 326 311 link_t *tmp = timeout_list.next; 327 312 while (tmp != &timeout_list) { 328 awaiter_t *cur 329 = list_get_instance(tmp, awaiter_t, to_event.link); 313 awaiter_t *cur; 330 314 315 cur = list_get_instance(tmp, awaiter_t, to_event.link); 331 316 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 332 317 break; 333 334 318 tmp = tmp->next; 335 319 } … … 348 332 * 349 333 * @return False if the call doesn't match any connection. 350 * @returnTrue if the call was passed to the respective connection fibril.334 * True if the call was passed to the respective connection fibril. 351 335 * 352 336 */ … … 485 469 * the first IPC_M_PHONE_HUNGUP call and continues to 486 470 * call async_get_call_timeout(). Repeat 487 * IPC_M_PHONE_HUNGUP until the caller notices. 471 * IPC_M_PHONE_HUNGUP until the caller notices. 488 472 */ 489 473 memset(call, 0, sizeof(ipc_call_t)); … … 492 476 return conn->close_callid; 493 477 } 494 478 495 479 if (usecs) 496 480 async_insert_timeout(&conn->wdata); … … 530 514 } 531 515 516 /** Default fibril function that gets called to handle new connection. 517 * 518 * This function is defined as a weak symbol - to be redefined in user code. 519 * 520 * @param callid Hash of the incoming call. 521 * @param call Data of the incoming call. 522 * 523 */ 524 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 525 { 526 ipc_answer_0(callid, ENOENT); 527 } 528 529 /** Default fibril function that gets called to handle interrupt notifications. 530 * 531 * This function is defined as a weak symbol - to be redefined in user code. 532 * 533 * @param callid Hash of the incoming call. 534 * @param call Data of the incoming call. 535 * 536 */ 537 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call) 538 { 539 } 540 532 541 /** Wrapper for client connection fibril. 533 542 * … … 542 551 static int connection_fibril(void *arg) 543 552 { 553 unsigned long key; 554 client_t *cl; 555 link_t *lnk; 556 bool destroy = false; 557 544 558 /* 545 559 * Setup fibril-local connection pointer. 546 560 */ 547 561 FIBRIL_connection = (connection_t *) arg; 548 549 futex_down(&async_futex); 550 562 551 563 /* 552 564 * Add our reference for the current connection in the client task … … 554 566 * hash in a new tracking structure. 555 567 */ 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 568 futex_down(&async_futex); 569 key = FIBRIL_connection->in_task_hash; 570 lnk = hash_table_find(&client_hash_table, &key); 562 571 if (lnk) { 563 cl ient= hash_table_get_instance(lnk, client_t, link);564 cl ient->refcnt++;572 cl = hash_table_get_instance(lnk, client_t, link); 573 cl->refcnt++; 565 574 } else { 566 cl ient= malloc(sizeof(client_t));567 if (!cl ient) {575 cl = malloc(sizeof(client_t)); 576 if (!cl) { 568 577 ipc_answer_0(FIBRIL_connection->callid, ENOMEM); 569 578 futex_up(&async_futex); 570 579 return 0; 571 580 } 572 573 client->in_task_hash = FIBRIL_connection->in_task_hash; 574 581 cl->in_task_hash = FIBRIL_connection->in_task_hash; 575 582 async_serialize_start(); 576 cl ient->data = async_client_data_create();583 cl->data = async_client_data_create(); 577 584 async_serialize_end(); 578 579 client->refcnt = 1; 580 hash_table_insert(&client_hash_table, &key, &client->link); 581 } 582 585 cl->refcnt = 1; 586 hash_table_insert(&client_hash_table, &key, &cl->link); 587 } 583 588 futex_up(&async_futex); 584 585 FIBRIL_connection->client = cl ient;586 589 590 FIBRIL_connection->client = cl; 591 587 592 /* 588 593 * Call the connection handler function. … … 594 599 * Remove the reference for this client task connection. 595 600 */ 596 bool destroy;597 598 601 futex_down(&async_futex); 599 600 if (--client->refcnt == 0) { 602 if (--cl->refcnt == 0) { 601 603 hash_table_remove(&client_hash_table, &key, 1); 602 604 destroy = true; 603 } else 604 destroy = false; 605 605 } 606 606 futex_up(&async_futex); 607 607 608 608 if (destroy) { 609 if (client->data) 610 async_client_data_destroy(client->data); 611 612 free(client); 613 } 614 609 if (cl->data) 610 async_client_data_destroy(cl->data); 611 free(cl); 612 } 613 615 614 /* 616 615 * Remove myself from the connection hash table. … … 625 624 */ 626 625 while (!list_empty(&FIBRIL_connection->msg_queue)) { 627 msg_t *msg = 628 list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, 629 link); 626 msg_t *msg; 630 627 628 msg = list_get_instance(FIBRIL_connection->msg_queue.next, 629 msg_t, link); 631 630 list_remove(&msg->link); 632 631 ipc_answer_0(msg->callid, EHANGUP); … … 671 670 if (callid) 672 671 ipc_answer_0(callid, ENOMEM); 673 674 672 return (uintptr_t) NULL; 675 673 } … … 719 717 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 720 718 { 721 /* Unrouted call - take some default action*/719 /* Unrouted call - do some default behaviour */ 722 720 if ((callid & IPC_CALLID_NOTIFICATION)) { 723 721 process_notification(callid, call); 724 return;722 goto out; 725 723 } 726 724 … … 728 726 case IPC_M_CONNECT_ME: 729 727 case IPC_M_CONNECT_ME_TO: 730 /* Open new connection with fibril ,etc. */728 /* Open new connection with fibril etc. */ 731 729 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call), 732 730 callid, call, client_connection); 733 return;731 goto out; 734 732 } 735 733 736 734 /* Try to route the call through the connection hash table */ 737 735 if (route_call(callid, call)) 738 return;736 goto out; 739 737 740 738 /* Unknown call from unknown phone - hang it up */ 741 739 ipc_answer_0(callid, EHANGUP); 740 return; 741 742 out: 743 ; 742 744 } 743 745 … … 752 754 link_t *cur = timeout_list.next; 753 755 while (cur != &timeout_list) { 754 awaiter_t *waiter = 755 list_get_instance(cur, awaiter_t, to_event.link); 756 awaiter_t *waiter; 756 757 758 waiter = list_get_instance(cur, awaiter_t, to_event.link); 757 759 if (tv_gt(&waiter->to_event.expires, &tv)) 758 760 break; 759 761 760 762 cur = cur->next; 761 763 762 764 list_remove(&waiter->to_event.link); 763 765 waiter->to_event.inlist = false; … … 786 788 while (true) { 787 789 if (fibril_switch(FIBRIL_FROM_MANAGER)) { 788 futex_up(&async_futex); 790 futex_up(&async_futex); 789 791 /* 790 792 * async_futex is always held when entering a manager … … 809 811 continue; 810 812 } else 811 timeout = tv_sub(&waiter->to_event.expires, &tv); 813 timeout = tv_sub(&waiter->to_event.expires, 814 &tv); 812 815 } else 813 816 timeout = SYNCH_NO_TIMEOUT; 814 817 815 818 futex_up(&async_futex); 816 819 817 820 atomic_inc(&threads_in_ipc_wait); 818 821 … … 822 825 823 826 atomic_dec(&threads_in_ipc_wait); 824 827 825 828 if (!callid) { 826 829 handle_expired_timeouts(); … … 872 875 /** Initialize the async framework. 873 876 * 874 */ 875 void __async_init(void) 877 * @return Zero on success or an error code. 878 */ 879 int __async_init(void) 876 880 { 877 881 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(); 882 &client_hash_table_ops) || !hash_table_create(&conn_hash_table, 883 CONN_HASH_TABLE_BUCKETS, 1, &conn_hash_table_ops)) { 884 return ENOMEM; 885 } 886 887 _async_sess_init(); 888 889 return 0; 884 890 } 885 891 … … 894 900 * @param retval Value returned in the answer. 895 901 * @param data Call data of the answer. 896 *897 902 */ 898 903 static void reply_received(void *arg, int retval, ipc_call_t *data) … … 942 947 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 943 948 { 944 amsg_t *msg = malloc(sizeof( amsg_t));949 amsg_t *msg = malloc(sizeof(*msg)); 945 950 946 951 if (!msg) … … 951 956 952 957 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 */ 958 /* We may sleep in the next method, but it will use its own mechanism */ 958 959 msg->wdata.active = true; 959 960 … … 986 987 ipc_call_t *dataptr) 987 988 { 988 amsg_t *msg = malloc(sizeof( amsg_t));989 amsg_t *msg = malloc(sizeof(*msg)); 989 990 990 991 if (!msg) … … 995 996 996 997 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 */ 998 /* We may sleep in next method, but it will use its own mechanism */ 1002 999 msg->wdata.active = true; 1003 1000 … … 1098 1095 void async_usleep(suseconds_t timeout) 1099 1096 { 1100 amsg_t *msg = malloc(sizeof( amsg_t));1097 amsg_t *msg = malloc(sizeof(*msg)); 1101 1098 1102 1099 if (!msg) … … 1310 1307 } 1311 1308 1312 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,1313 sysarg_t arg1, sysarg_t arg2, unsignedint mode)1309 int async_forward_fast(ipc_callid_t callid, int phoneid, int imethod, 1310 sysarg_t arg1, sysarg_t arg2, int mode) 1314 1311 { 1315 1312 return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode); 1316 1313 } 1317 1314 1318 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,1315 int async_forward_slow(ipc_callid_t callid, int phoneid, int imethod, 1319 1316 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 1320 unsignedint mode)1317 int mode) 1321 1318 { 1322 1319 return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4, … … 1431 1428 } 1432 1429 1433 /** Wrapper for IPC_M_SHARE_IN calls using the async framework.1434 * 1435 * @param phoneid 1436 * @param dst 1437 * @param size 1438 * @param arg 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 * 1430 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework. 1431 * 1432 * @param phoneid Phone that will be used to contact the receiving side. 1433 * @param dst Destination address space area base. 1434 * @param size Size of the destination address space area. 1435 * @param arg User defined argument. 1436 * @param flags Storage where the received flags will be stored. Can be 1437 * NULL. 1438 * 1439 * @return Zero on success or a negative error code from errno.h. 1443 1440 */ 1444 1441 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 1445 unsigned int *flags) 1446 { 1442 int *flags) 1443 { 1444 int res; 1447 1445 sysarg_t tmp_flags; 1448 intres = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,1446 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst, 1449 1447 (sysarg_t) size, arg, NULL, &tmp_flags); 1450 1451 1448 if (flags) 1452 *flags = (unsigned int) tmp_flags; 1453 1449 *flags = tmp_flags; 1454 1450 return res; 1455 1451 } … … 1457 1453 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework. 1458 1454 * 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. 1455 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls 1456 * so that the user doesn't have to remember the meaning of each IPC argument. 1462 1457 * 1463 1458 * So far, this wrapper is to be used from within a connection fibril. 1464 1459 * 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 { 1460 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will 1461 * be stored. 1462 * @param size Destination address space area size. 1463 * 1464 * @return Non-zero on success, zero on failure. 1465 */ 1466 int async_share_in_receive(ipc_callid_t *callid, size_t *size) 1467 { 1468 ipc_call_t data; 1469 1473 1470 assert(callid); 1474 1471 assert(size); 1475 1476 ipc_call_t data; 1472 1477 1473 *callid = async_get_call(&data); 1478 1479 1474 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN) 1480 return false; 1481 1475 return 0; 1482 1476 *size = (size_t) IPC_GET_ARG2(data); 1483 return true;1477 return 1; 1484 1478 } 1485 1479 1486 1480 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework. 1487 1481 * 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) 1482 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1483 * so that the user doesn't have to remember the meaning of each IPC argument. 1484 * 1485 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1486 * @param src Source address space base. 1487 * @param flags Flags to be used for sharing. Bits can be only cleared. 1488 * 1489 * @return Zero on success or a value from @ref errno.h on failure. 1490 */ 1491 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags) 1500 1492 { 1501 1493 return ipc_share_in_finalize(callid, src, flags); 1502 1494 } 1503 1495 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) 1496 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework. 1497 * 1498 * @param phoneid Phone that will be used to contact the receiving side. 1499 * @param src Source address space area base address. 1500 * @param flags Flags to be used for sharing. Bits can be only cleared. 1501 * 1502 * @return Zero on success or a negative error code from errno.h. 1503 */ 1504 int async_share_out_start(int phoneid, void *src, int flags) 1514 1505 { 1515 1506 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, … … 1519 1510 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework. 1520 1511 * 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. 1512 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls 1513 * so that the user doesn't have to remember the meaning of each IPC argument. 1524 1514 * 1525 1515 * So far, this wrapper is to be used from within a connection fibril. 1526 1516 * 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 { 1517 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will 1518 * be stored. 1519 * @param size Storage where the source address space area size will be 1520 * stored. 1521 * @param flags Storage where the sharing flags will be stored. 1522 * 1523 * @return Non-zero on success, zero on failure. 1524 */ 1525 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags) 1526 { 1527 ipc_call_t data; 1528 1536 1529 assert(callid); 1537 1530 assert(size); 1538 1531 assert(flags); 1539 1540 ipc_call_t data; 1532 1541 1533 *callid = async_get_call(&data); 1542 1543 1534 if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT) 1544 return false; 1545 1535 return 0; 1546 1536 *size = (size_t) IPC_GET_ARG2(data); 1547 *flags = ( unsignedint) IPC_GET_ARG3(data);1548 return true;1537 *flags = (int) IPC_GET_ARG3(data); 1538 return 1; 1549 1539 } 1550 1540 1551 1541 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework. 1552 1542 * 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 * 1543 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 1544 * so that the user doesn't have to remember the meaning of each IPC argument. 1545 * 1546 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1547 * @param dst Destination address space area base address. 1548 * 1549 * @return Zero on success or a value from @ref errno.h on failure. 1562 1550 */ 1563 1551 int async_share_out_finalize(ipc_callid_t callid, void *dst) … … 1566 1554 } 1567 1555 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 * 1556 1557 /** Wrapper for making IPC_M_DATA_READ calls using the async framework. 1558 * 1559 * @param phoneid Phone that will be used to contact the receiving side. 1560 * @param dst Address of the beginning of the destination buffer. 1561 * @param size Size of the destination buffer. 1562 * 1563 * @return Zero on success or a negative error code from errno.h. 1576 1564 */ 1577 1565 int async_data_read_start(int phoneid, void *dst, size_t size) … … 1583 1571 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework. 1584 1572 * 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. 1573 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 1574 * so that the user doesn't have to remember the meaning of each IPC argument. 1588 1575 * 1589 1576 * So far, this wrapper is to be used from within a connection fibril. 1590 1577 * 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 { 1578 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 1579 * be stored. 1580 * @param size Storage where the maximum size will be stored. Can be 1581 * NULL. 1582 * 1583 * @return Non-zero on success, zero on failure. 1584 */ 1585 int async_data_read_receive(ipc_callid_t *callid, size_t *size) 1586 { 1587 ipc_call_t data; 1588 1599 1589 assert(callid); 1600 1601 ipc_call_t data; 1590 1602 1591 *callid = async_get_call(&data); 1603 1604 1592 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ) 1605 return false; 1606 1593 return 0; 1607 1594 if (size) 1608 1595 *size = (size_t) IPC_GET_ARG2(data); 1609 1610 return true; 1596 return 1; 1611 1597 } 1612 1598 1613 1599 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework. 1614 1600 * 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 * 1601 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1602 * so that the user doesn't have to remember the meaning of each IPC argument. 1603 * 1604 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1605 * @param src Source address for the IPC_M_DATA_READ call. 1606 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1607 * the maximum size announced by the sender. 1608 * 1609 * @return Zero on success or a value from @ref errno.h on failure. 1626 1610 */ 1627 1611 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) … … 1663 1647 } 1664 1648 1665 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.1649 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1666 1650 * 1667 1651 * @param phoneid Phone that will be used to contact the receiving side. … … 1680 1664 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework. 1681 1665 * 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. 1666 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls 1667 * so that the user doesn't have to remember the meaning of each IPC argument. 1685 1668 * 1686 1669 * So far, this wrapper is to be used from within a connection fibril. 1687 1670 * 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 { 1671 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1672 * be stored. 1673 * @param size Storage where the suggested size will be stored. May be 1674 * NULL 1675 * 1676 * @return Non-zero on success, zero on failure. 1677 * 1678 */ 1679 int async_data_write_receive(ipc_callid_t *callid, size_t *size) 1680 { 1681 ipc_call_t data; 1682 1696 1683 assert(callid); 1697 1684 1698 ipc_call_t data;1699 1685 *callid = async_get_call(&data); 1700 1701 1686 if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE) 1702 return false;1687 return 0; 1703 1688 1704 1689 if (size) 1705 1690 *size = (size_t) IPC_GET_ARG2(data); 1706 1691 1707 return true;1692 return 1; 1708 1693 } 1709 1694 1710 1695 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework. 1711 1696 * 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. 1697 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 1698 * so that the user doesn't have to remember the meaning of each IPC argument. 1715 1699 * 1716 1700 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. … … 1808 1792 * 1809 1793 */ 1810 void async_data_write_void( sysarg_t retval)1794 void async_data_write_void(const int retval) 1811 1795 { 1812 1796 ipc_callid_t callid;
Note:
See TracChangeset
for help on using the changeset viewer.