Rev 3386 | Rev 4581 | 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()...*/ |