Rev 1694 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1694 | Rev 1719 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | /** @addtogroup libc |
29 | /** @addtogroup libc |
30 | * @{ |
30 | * @{ |
31 | */ |
31 | */ |
32 | /** @file |
32 | /** @file |
33 | */ |
33 | */ |
34 | 34 | ||
Line 371... | Line 371... | ||
371 | int close_answered = 0; |
371 | int close_answered = 0; |
372 | 372 | ||
373 | /* Setup thread local connection pointer */ |
373 | /* Setup thread local connection pointer */ |
374 | PS_connection = (connection_t *)arg; |
374 | PS_connection = (connection_t *)arg; |
375 | PS_connection->cthread(PS_connection->callid, &PS_connection->call); |
375 | PS_connection->cthread(PS_connection->callid, &PS_connection->call); |
- | 376 | ||
376 | /* Remove myself from connection hash table */ |
377 | /* Remove myself from connection hash table */ |
377 | futex_down(&async_futex); |
378 | futex_down(&async_futex); |
378 | key = PS_connection->in_phone_hash; |
379 | key = PS_connection->in_phone_hash; |
379 | hash_table_remove(&conn_hash_table, &key, 1); |
380 | hash_table_remove(&conn_hash_table, &key, 1); |
380 | futex_up(&async_futex); |
381 | futex_up(&async_futex); |
- | 382 | ||
381 | /* Answer all remaining messages with ehangup */ |
383 | /* Answer all remaining messages with ehangup */ |
382 | while (!list_empty(&PS_connection->msg_queue)) { |
384 | while (!list_empty(&PS_connection->msg_queue)) { |
383 | msg = list_get_instance(PS_connection->msg_queue.next, msg_t, link); |
385 | msg = list_get_instance(PS_connection->msg_queue.next, msg_t, link); |
384 | list_remove(&msg->link); |
386 | list_remove(&msg->link); |
385 | if (msg->callid == PS_connection->close_callid) |
387 | if (msg->callid == PS_connection->close_callid) |
Line 387... | Line 389... | ||
387 | ipc_answer_fast(msg->callid, EHANGUP, 0, 0); |
389 | ipc_answer_fast(msg->callid, EHANGUP, 0, 0); |
388 | free(msg); |
390 | free(msg); |
389 | } |
391 | } |
390 | if (PS_connection->close_callid) |
392 | if (PS_connection->close_callid) |
391 | ipc_answer_fast(PS_connection->close_callid, 0, 0, 0); |
393 | ipc_answer_fast(PS_connection->close_callid, 0, 0, 0); |
- | 394 | ||
- | 395 | return 0; |
|
392 | } |
396 | } |
393 | 397 | ||
394 | /** Create new thread for a new connection |
398 | /** Create new thread for a new connection |
395 | * |
399 | * |
396 | * Creates new thread for connection, fills in connection |
400 | * Creates new thread for connection, fills in connection |
Line 403... | Line 407... | ||
403 | * @param call Call data of the opening packet |
407 | * @param call Call data of the opening packet |
404 | * @param cthread Thread function that should be called upon |
408 | * @param cthread Thread function that should be called upon |
405 | * opening the connection |
409 | * opening the connection |
406 | * @return New thread id |
410 | * @return New thread id |
407 | */ |
411 | */ |
408 | pstid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid, |
412 | pstid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid, ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *)) |
409 | ipc_call_t *call, |
- | |
410 | void (*cthread)(ipc_callid_t,ipc_call_t *)) |
- | |
411 | { |
413 | { |
412 | pstid_t ptid; |
- | |
413 | connection_t *conn; |
414 | connection_t *conn; |
414 | unsigned long key; |
415 | unsigned long key; |
415 | 416 | ||
416 | conn = malloc(sizeof(*conn)); |
417 | conn = malloc(sizeof(*conn)); |
417 | if (!conn) { |
418 | if (!conn) { |
Line 512... | Line 513... | ||
512 | awaiter_t *waiter; |
513 | awaiter_t *waiter; |
513 | struct timeval tv; |
514 | struct timeval tv; |
514 | 515 | ||
515 | while (1) { |
516 | while (1) { |
516 | if (psthread_schedule_next_adv(PS_FROM_MANAGER)) { |
517 | if (psthread_schedule_next_adv(PS_FROM_MANAGER)) { |
- | 518 | futex_up(&async_futex); |
|
517 | futex_up(&async_futex); /* async_futex is always held |
519 | /* async_futex is always held |
518 | * when entering manager thread |
520 | * when entering manager thread |
519 | */ |
521 | */ |
520 | continue; |
522 | continue; |
521 | } |
523 | } |
522 | futex_down(&async_futex); |
524 | futex_down(&async_futex); |
523 | if (!list_empty(&timeout_list)) { |
525 | if (!list_empty(&timeout_list)) { |
524 | waiter = list_get_instance(timeout_list.next,awaiter_t,link); |
526 | waiter = list_get_instance(timeout_list.next,awaiter_t,link); |
Line 544... | Line 546... | ||
544 | continue; |
546 | continue; |
545 | } |
547 | } |
546 | 548 | ||
547 | handle_call(callid, &call); |
549 | handle_call(callid, &call); |
548 | } |
550 | } |
- | 551 | ||
- | 552 | return 0; |
|
549 | } |
553 | } |
550 | 554 | ||
551 | /** Function to start async_manager as a standalone thread |
555 | /** Function to start async_manager as a standalone thread |
552 | * |
556 | * |
553 | * When more kernel threads are used, one async manager should |
557 | * When more kernel threads are used, one async manager should |
Line 555... | Line 559... | ||
555 | * currently one async_manager is started automatically per kernel |
559 | * currently one async_manager is started automatically per kernel |
556 | * thread except main thread. |
560 | * thread except main thread. |
557 | */ |
561 | */ |
558 | static int async_manager_thread(void *arg) |
562 | static int async_manager_thread(void *arg) |
559 | { |
563 | { |
- | 564 | futex_up(&async_futex); |
|
560 | futex_up(&async_futex); /* async_futex is always locked when entering |
565 | /* async_futex is always locked when entering |
561 | * manager */ |
566 | * manager */ |
562 | async_manager_worker(); |
567 | async_manager_worker(); |
- | 568 | ||
- | 569 | return 0; |
|
563 | } |
570 | } |
564 | 571 | ||
565 | /** Add one manager to manager list */ |
572 | /** Add one manager to manager list */ |
566 | void async_create_manager(void) |
573 | void async_create_manager(void) |
567 | { |
574 | { |
Line 583... | Line 590... | ||
583 | if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1, &conn_hash_table_ops)) { |
590 | if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1, &conn_hash_table_ops)) { |
584 | printf("%s: cannot create hash table\n", "async"); |
591 | printf("%s: cannot create hash table\n", "async"); |
585 | return ENOMEM; |
592 | return ENOMEM; |
586 | } |
593 | } |
587 | 594 | ||
- | 595 | return 0; |
|
588 | } |
596 | } |
589 | 597 | ||
590 | /** IPC handler for messages in async framework |
598 | /** IPC handler for messages in async framework |
591 | * |
599 | * |
592 | * Notify thread that is waiting for this message, that it arrived |
600 | * Notify thread that is waiting for this message, that it arrived |
Line 677... | Line 685... | ||
677 | * |
685 | * |
678 | */ |
686 | */ |
679 | void async_wait_for(aid_t amsgid, ipcarg_t *retval) |
687 | void async_wait_for(aid_t amsgid, ipcarg_t *retval) |
680 | { |
688 | { |
681 | amsg_t *msg = (amsg_t *) amsgid; |
689 | amsg_t *msg = (amsg_t *) amsgid; |
682 | connection_t *conn; |
- | |
683 | 690 | ||
684 | futex_down(&async_futex); |
691 | futex_down(&async_futex); |
685 | if (msg->done) { |
692 | if (msg->done) { |
686 | futex_up(&async_futex); |
693 | futex_up(&async_futex); |
687 | goto done; |
694 | goto done; |
Line 709... | Line 716... | ||
709 | * |
716 | * |
710 | */ |
717 | */ |
711 | int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout) |
718 | int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout) |
712 | { |
719 | { |
713 | amsg_t *msg = (amsg_t *) amsgid; |
720 | amsg_t *msg = (amsg_t *) amsgid; |
714 | connection_t *conn; |
- | |
715 | 721 | ||
716 | /* TODO: Let it go through the event read at least once */ |
722 | /* TODO: Let it go through the event read at least once */ |
717 | if (timeout < 0) |
723 | if (timeout < 0) |
718 | return ETIMEOUT; |
724 | return ETIMEOUT; |
719 | 725 | ||
Line 800... | Line 806... | ||
800 | { |
806 | { |
801 | ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, !in_interrupt_handler); |
807 | ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, !in_interrupt_handler); |
802 | } |
808 | } |
803 | 809 | ||
804 | 810 | ||
805 | /** @} |
811 | /** @} |
806 | */ |
812 | */ |
807 | - | ||
808 | - |