Subversion Repositories HelenOS-historic

Rev

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
 
-