Subversion Repositories HelenOS

Rev

Rev 3149 | Rev 4348 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3149 Rev 4338
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()...*/