Rev 3386 | Rev 4327 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3386 | Rev 4153 | ||
|---|---|---|---|
| Line 481... | Line 481... | ||
| 481 | fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
481 | fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
| 482 | ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *)) |
482 | ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *)) |
| 483 | { |
483 | { |
| 484 | connection_t *conn; |
484 | connection_t *conn; |
| 485 | unsigned long key; |
485 | unsigned long key; |
| 486 | 486 | ||
| 487 | conn = malloc(sizeof(*conn)); |
487 | conn = malloc(sizeof(*conn)); |
| 488 | if (!conn) { |
488 | if (!conn) { |
| 489 | if (callid) |
489 | if (callid) |
| 490 | ipc_answer_0(callid, ENOMEM); |
490 | ipc_answer_0(callid, ENOMEM); |
| 491 | return NULL; |
491 | return NULL; |
| Line 496... | Line 496... | ||
| 496 | conn->close_callid = 0; |
496 | conn->close_callid = 0; |
| 497 | if (call) |
497 | if (call) |
| 498 | conn->call = *call; |
498 | conn->call = *call; |
| 499 | conn->wdata.active = 1; /* We will activate the fibril ASAP */ |
499 | conn->wdata.active = 1; /* We will activate the fibril ASAP */ |
| 500 | conn->cfibril = cfibril; |
500 | conn->cfibril = cfibril; |
| 501 | 501 | ||
| 502 | conn->wdata.fid = fibril_create(connection_fibril, conn); |
502 | conn->wdata.fid = fibril_create(connection_fibril, conn); |
| 503 | if (!conn->wdata.fid) { |
503 | if (!conn->wdata.fid) { |
| 504 | free(conn); |
504 | free(conn); |
| 505 | if (callid) |
505 | if (callid) |
| 506 | ipc_answer_0(callid, ENOMEM); |
506 | ipc_answer_0(callid, ENOMEM); |
| 507 | return NULL; |
507 | return NULL; |
| 508 | } |
508 | } |
| - | 509 | ||
| 509 | /* Add connection to the connection hash table */ |
510 | /* Add connection to the connection hash table */ |
| 510 | key = conn->in_phone_hash; |
511 | key = conn->in_phone_hash; |
| 511 | futex_down(&async_futex); |
512 | futex_down(&async_futex); |
| 512 | hash_table_insert(&conn_hash_table, &key, &conn->link); |
513 | hash_table_insert(&conn_hash_table, &key, &conn->link); |
| 513 | futex_up(&async_futex); |
514 | futex_up(&async_futex); |
| 514 | 515 | ||
| 515 | fibril_add_ready(conn->wdata.fid); |
516 | fibril_add_ready(conn->wdata.fid); |
| 516 | 517 | ||
| 517 | return conn->wdata.fid; |
518 | return conn->wdata.fid; |
| 518 | } |
519 | } |
| 519 | 520 | ||
| 520 | /** Handle a call that was received. |
521 | /** Handle a call that was received. |
| 521 | * |
522 | * |
| 522 | * If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created. |
523 | * If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created. |
| 523 | * Otherwise the call is routed to its connection fibril. |
524 | * Otherwise the call is routed to its connection fibril. |
| 524 | * |
525 | * |
| 525 | * @param callid Hash of the incoming call. |
526 | * @param callid Hash of the incoming call. |
| 526 | * @param call Data of the incoming call. |
527 | * @param call Data of the incoming call. |
| - | 528 | * |
|
| 527 | */ |
529 | */ |
| 528 | static void handle_call(ipc_callid_t callid, ipc_call_t *call) |
530 | static void handle_call(ipc_callid_t callid, ipc_call_t *call) |
| 529 | { |
531 | { |
| 530 | /* Unrouted call - do some default behaviour */ |
532 | /* Unrouted call - do some default behaviour */ |
| 531 | if ((callid & IPC_CALLID_NOTIFICATION)) { |
533 | if ((callid & IPC_CALLID_NOTIFICATION)) { |
| 532 | _in_interrupt_handler = 1; |
534 | _in_interrupt_handler = 1; |
| 533 | (*interrupt_received)(callid, call); |
535 | (*interrupt_received)(callid, call); |
| 534 | _in_interrupt_handler = 0; |
536 | _in_interrupt_handler = 0; |
| 535 | return; |
537 | return; |
| 536 | } |
538 | } |
| 537 | 539 | ||
| 538 | switch (IPC_GET_METHOD(*call)) { |
540 | switch (IPC_GET_METHOD(*call)) { |
| 539 | case IPC_M_CONNECT_ME_TO: |
541 | case IPC_M_CONNECT_ME_TO: |
| 540 | /* Open new connection with fibril etc. */ |
542 | /* Open new connection with fibril etc. */ |
| 541 | async_new_connection(IPC_GET_ARG5(*call), callid, call, |
543 | async_new_connection(IPC_GET_ARG5(*call), callid, call, |
| 542 | client_connection); |
544 | client_connection); |
| 543 | return; |
545 | return; |
| 544 | } |
546 | } |
| 545 | 547 | ||
| 546 | /* Try to route the call through the connection hash table */ |
548 | /* Try to route the call through the connection hash table */ |
| 547 | if (route_call(callid, call)) |
549 | if (route_call(callid, call)) |
| 548 | return; |
550 | return; |
| 549 | 551 | ||
| 550 | /* Unknown call from unknown phone - hang it up */ |
552 | /* Unknown call from unknown phone - hang it up */ |
| 551 | ipc_answer_0(callid, EHANGUP); |
553 | ipc_answer_0(callid, EHANGUP); |
| 552 | } |
554 | } |
| 553 | 555 | ||
| 554 | /** Fire all timeouts that expired. */ |
556 | /** Fire all timeouts that expired. */ |
| Line 737... | Line 739... | ||
| 737 | */ |
739 | */ |
| 738 | aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
740 | aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
| 739 | ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) |
741 | ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) |
| 740 | { |
742 | { |
| 741 | amsg_t *msg; |
743 | amsg_t *msg; |
| 742 | - | ||
| 743 | if (_in_interrupt_handler) { |
- | |
| 744 | printf("Cannot send asynchronous request in interrupt " |
- | |
| 745 | "handler.\n"); |
- | |
| 746 | _exit(1); |
- | |
| 747 | } |
744 | |
| 748 | - | ||
| 749 | msg = malloc(sizeof(*msg)); |
745 | msg = malloc(sizeof(*msg)); |
| 750 | msg->done = 0; |
746 | msg->done = 0; |
| 751 | msg->dataptr = dataptr; |
747 | msg->dataptr = dataptr; |
| 752 | 748 | ||
| 753 | /* We may sleep in the next method, but it will use its own mechanism */ |
749 | /* We may sleep in the next method, but it will use its own mechanism */ |
| 754 | msg->wdata.active = 1; |
750 | msg->wdata.active = 1; |
| 755 | 751 | ||
| 756 | ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg, |
752 | ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg, |
| 757 | reply_received, 1); |
753 | reply_received, !_in_interrupt_handler); |
| 758 | 754 | ||
| 759 | return (aid_t) msg; |
755 | return (aid_t) msg; |
| 760 | } |
756 | } |
| 761 | 757 | ||
| 762 | /** Send message and return id of the sent message |
758 | /** Send message and return id of the sent message |
| 763 | * |
759 | * |
| Line 779... | Line 775... | ||
| 779 | aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
775 | aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
| 780 | ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
776 | ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
| 781 | ipc_call_t *dataptr) |
777 | ipc_call_t *dataptr) |
| 782 | { |
778 | { |
| 783 | amsg_t *msg; |
779 | amsg_t *msg; |
| 784 | - | ||
| 785 | if (_in_interrupt_handler) { |
- | |
| 786 | printf("Cannot send asynchronous request in interrupt " |
- | |
| 787 | "handler.\n"); |
- | |
| 788 | _exit(1); |
- | |
| 789 | } |
780 | |
| 790 | - | ||
| 791 | msg = malloc(sizeof(*msg)); |
781 | msg = malloc(sizeof(*msg)); |
| 792 | msg->done = 0; |
782 | msg->done = 0; |
| 793 | msg->dataptr = dataptr; |
783 | msg->dataptr = dataptr; |
| 794 | 784 | ||
| 795 | /* We may sleep in next method, but it will use its own mechanism */ |
785 | /* We may sleep in next method, but it will use its own mechanism */ |
| 796 | msg->wdata.active = 1; |
786 | msg->wdata.active = 1; |
| 797 | 787 | ||
| 798 | ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg, |
788 | ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg, |
| 799 | reply_received, 1); |
789 | reply_received, !_in_interrupt_handler); |
| 800 | 790 | ||
| 801 | return (aid_t) msg; |
791 | return (aid_t) msg; |
| 802 | } |
792 | } |
| 803 | 793 | ||
| 804 | /** Wait for a message sent by the async framework. |
794 | /** Wait for a message sent by the async framework. |
| 805 | * |
795 | * |
| Line 882... | Line 872... | ||
| 882 | */ |
872 | */ |
| 883 | void async_usleep(suseconds_t timeout) |
873 | void async_usleep(suseconds_t timeout) |
| 884 | { |
874 | { |
| 885 | amsg_t *msg; |
875 | amsg_t *msg; |
| 886 | 876 | ||
| 887 | if (_in_interrupt_handler) { |
- | |
| 888 | printf("Cannot call async_usleep in interrupt handler.\n"); |
- | |
| 889 | _exit(1); |
- | |
| 890 | } |
- | |
| 891 | - | ||
| 892 | msg = malloc(sizeof(*msg)); |
877 | msg = malloc(sizeof(*msg)); |
| 893 | if (!msg) |
878 | if (!msg) |
| 894 | return; |
879 | return; |
| 895 | 880 | ||
| 896 | msg->wdata.fid = fibril_get_id(); |
881 | msg->wdata.fid = fibril_get_id(); |
| 897 | msg->wdata.active = 0; |
882 | msg->wdata.active = 0; |
| 898 | 883 | ||
| 899 | gettimeofday(&msg->wdata.expires, NULL); |
884 | gettimeofday(&msg->wdata.expires, NULL); |
| 900 | tv_add(&msg->wdata.expires, timeout); |
885 | tv_add(&msg->wdata.expires, timeout); |
| 901 | 886 | ||
| 902 | futex_down(&async_futex); |
887 | futex_down(&async_futex); |
| 903 | insert_timeout(&msg->wdata); |
888 | insert_timeout(&msg->wdata); |
| 904 | /* Leave the async_futex locked when entering this function */ |
889 | /* Leave the async_futex locked when entering this function */ |
| 905 | fibril_switch(FIBRIL_TO_MANAGER); |
890 | fibril_switch(FIBRIL_TO_MANAGER); |
| 906 | /* futex is up automatically after fibril_switch()...*/ |
891 | /* futex is up automatically after fibril_switch()...*/ |