Rev 1694 | 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 | - | ||