Subversion Repositories HelenOS

Rev

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

Rev 4407 Rev 4475
Line 176... Line 176...
176
/** Identifier of the incoming connection handled by the current fibril. */
176
/** Identifier of the incoming connection handled by the current fibril. */
177
__thread connection_t *FIBRIL_connection;
177
__thread connection_t *FIBRIL_connection;
178
 
178
 
179
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
179
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
180
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
180
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
-
 
181
static void default_pending(void);
181
 
182
 
182
/**
183
/**
183
 * Pointer to a fibril function that will be used to handle connections.
184
 * Pointer to a fibril function that will be used to handle connections.
184
 */
185
 */
185
static async_client_conn_t client_connection = default_client_connection;
186
static async_client_conn_t client_connection = default_client_connection;
Line 188... Line 189...
188
 * Pointer to a fibril function that will be used to handle interrupt
189
 * Pointer to a fibril function that will be used to handle interrupt
189
 * notifications.
190
 * notifications.
190
 */
191
 */
191
static async_client_conn_t interrupt_received = default_interrupt_received;
192
static async_client_conn_t interrupt_received = default_interrupt_received;
192
 
193
 
-
 
194
/**
-
 
195
 * Pointer to a fibril function that will be used to handle pending
-
 
196
 * operations.
-
 
197
 */
-
 
198
static async_pending_t pending = default_pending;
193
 
199
 
194
static hash_table_t conn_hash_table;
200
static hash_table_t conn_hash_table;
195
static LIST_INITIALIZE(timeout_list);
201
static LIST_INITIALIZE(timeout_list);
196
 
202
 
197
 
-
 
198
#define CONN_HASH_TABLE_CHAINS  32
203
#define CONN_HASH_TABLE_CHAINS  32
199
 
204
 
200
/** Compute hash into the connection hash table based on the source phone hash.
205
/** Compute hash into the connection hash table based on the source phone hash.
201
 *
206
 *
202
 * @param key Pointer to source phone hash.
207
 * @param key Pointer to source phone hash.
Line 374... Line 379...
374
   
379
   
375
    futex_up(&async_futex);
380
    futex_up(&async_futex);
376
    return true;
381
    return true;
377
}
382
}
378
 
383
 
-
 
384
/** Pending fibril.
-
 
385
 *
-
 
386
 * After each call the pending operations are executed in a separate
-
 
387
 * fibril. The function pending() is c.
-
 
388
 *
-
 
389
 * @param arg Unused.
-
 
390
 *
-
 
391
 * @return Always zero.
-
 
392
 *
-
 
393
 */
-
 
394
static int pending_fibril(void *arg)
-
 
395
{
-
 
396
    pending();
-
 
397
   
-
 
398
    return 0;
-
 
399
}
-
 
400
 
-
 
401
/** Process pending actions.
-
 
402
 *
-
 
403
 * A new fibril is created which would process the pending operations.
-
 
404
 *
-
 
405
 * @return False if an error occured.
-
 
406
 *         True if the execution was passed to the pending fibril.
-
 
407
 *
-
 
408
 */
-
 
409
static bool process_pending(void)
-
 
410
{
-
 
411
    futex_down(&async_futex);
-
 
412
   
-
 
413
    fid_t fid = fibril_create(pending_fibril, NULL);
-
 
414
    fibril_add_ready(fid);
-
 
415
   
-
 
416
    futex_up(&async_futex);
-
 
417
    return true;
-
 
418
}
-
 
419
 
379
/** Return new incoming message for the current (fibril-local) connection.
420
/** Return new incoming message for the current (fibril-local) connection.
380
 *
421
 *
381
 * @param call  Storage where the incoming call data will be stored.
422
 * @param call  Storage where the incoming call data will be stored.
382
 * @param usecs Timeout in microseconds. Zero denotes no timeout.
423
 * @param usecs Timeout in microseconds. Zero denotes no timeout.
383
 *
424
 *
Line 470... Line 511...
470
 */
511
 */
471
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
512
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
472
{
513
{
473
}
514
}
474
 
515
 
-
 
516
/** Default fibril function that gets called to handle pending operations.
-
 
517
 *
-
 
518
 * This function is defined as a weak symbol - to be redefined in user code.
-
 
519
 *
-
 
520
 */
-
 
521
static void default_pending(void)
-
 
522
{
-
 
523
}
-
 
524
 
475
/** Wrapper for client connection fibril.
525
/** Wrapper for client connection fibril.
476
 *
526
 *
477
 * When a new connection arrives, a fibril with this implementing function is
527
 * When a new connection arrives, a fibril with this implementing function is
478
 * created. It calls client_connection() and does the final cleanup.
528
 * created. It calls client_connection() and does the final cleanup.
479
 *
529
 *
Line 561... Line 611...
561
            ipc_answer_0(callid, ENOMEM);
611
            ipc_answer_0(callid, ENOMEM);
562
        return NULL;
612
        return NULL;
563
    }
613
    }
564
   
614
   
565
    /* Add connection to the connection hash table */
615
    /* Add connection to the connection hash table */
566
    ipcarg_t key = conn->in_phone_hash;
616
    unsigned long key = conn->in_phone_hash;
567
   
617
   
568
    futex_down(&async_futex);
618
    futex_down(&async_futex);
569
    hash_table_insert(&conn_hash_table, &key, &conn->link);
619
    hash_table_insert(&conn_hash_table, &key, &conn->link);
570
    futex_up(&async_futex);
620
    futex_up(&async_futex);
571
   
621
   
Line 586... Line 636...
586
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
636
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
587
{
637
{
588
    /* Unrouted call - do some default behaviour */
638
    /* Unrouted call - do some default behaviour */
589
    if ((callid & IPC_CALLID_NOTIFICATION)) {
639
    if ((callid & IPC_CALLID_NOTIFICATION)) {
590
        process_notification(callid, call);
640
        process_notification(callid, call);
591
        return;
641
        goto out;
592
    }
642
    }
593
   
643
   
594
    switch (IPC_GET_METHOD(*call)) {
644
    switch (IPC_GET_METHOD(*call)) {
595
    case IPC_M_CONNECT_ME:
645
    case IPC_M_CONNECT_ME:
596
    case IPC_M_CONNECT_ME_TO:
646
    case IPC_M_CONNECT_ME_TO:
597
        /* Open new connection with fibril etc. */
647
        /* Open new connection with fibril etc. */
598
        async_new_connection(IPC_GET_ARG5(*call), callid, call,
648
        async_new_connection(IPC_GET_ARG5(*call), callid, call,
599
            client_connection);
649
            client_connection);
600
        return;
650
        goto out;
601
    }
651
    }
602
   
652
   
603
    /* Try to route the call through the connection hash table */
653
    /* Try to route the call through the connection hash table */
604
    if (route_call(callid, call))
654
    if (route_call(callid, call))
605
        return;
655
        goto out;
606
   
656
   
607
    /* Unknown call from unknown phone - hang it up */
657
    /* Unknown call from unknown phone - hang it up */
608
    ipc_answer_0(callid, EHANGUP);
658
    ipc_answer_0(callid, EHANGUP);
-
 
659
    return;
-
 
660
   
-
 
661
out:
-
 
662
    process_pending();
609
}
663
}
610
 
664
 
611
/** Fire all timeouts that expired. */
665
/** Fire all timeouts that expired. */
612
static void handle_expired_timeouts(void)
666
static void handle_expired_timeouts(void)
613
{
667
{
Line 757... Line 811...
757
 * @param retval Value returned in the answer.
811
 * @param retval Value returned in the answer.
758
 * @param data   Call data of the answer.
812
 * @param data   Call data of the answer.
759
 */
813
 */
760
static void reply_received(void *arg, int retval, ipc_call_t *data)
814
static void reply_received(void *arg, int retval, ipc_call_t *data)
761
{
815
{
-
 
816
    futex_down(&async_futex);
-
 
817
   
762
    amsg_t *msg = (amsg_t *) arg;
818
    amsg_t *msg = (amsg_t *) arg;
763
    msg->retval = retval;
819
    msg->retval = retval;
764
   
820
   
765
    futex_down(&async_futex);
-
 
766
   
-
 
767
    /* Copy data after futex_down, just in case the call was detached */
821
    /* Copy data after futex_down, just in case the call was detached */
768
    if (msg->dataptr)
822
    if ((msg->dataptr) && (data))
769
        *msg->dataptr = *data;
823
        *msg->dataptr = *data;
770
   
824
   
771
    write_barrier();
825
    write_barrier();
772
   
826
   
773
    /* Remove message from timeout list */
827
    /* Remove message from timeout list */
Line 992... Line 1046...
992
void async_set_interrupt_received(async_client_conn_t intr)
1046
void async_set_interrupt_received(async_client_conn_t intr)
993
{
1047
{
994
    interrupt_received = intr;
1048
    interrupt_received = intr;
995
}
1049
}
996
 
1050
 
-
 
1051
/** Setter for pending function pointer.
-
 
1052
 *
-
 
1053
 * @param pend Function that will implement a new pending
-
 
1054
 *             operations fibril.
-
 
1055
 */
-
 
1056
void async_set_pending(async_pending_t pend)
-
 
1057
{
-
 
1058
    pending = pend;
-
 
1059
}
-
 
1060
 
997
/** Pseudo-synchronous message sending - fast version.
1061
/** Pseudo-synchronous message sending - fast version.
998
 *
1062
 *
999
 * Send message asynchronously and return only after the reply arrives.
1063
 * Send message asynchronously and return only after the reply arrives.
1000
 *
1064
 *
1001
 * This function can only transfer 4 register payload arguments. For
1065
 * This function can only transfer 4 register payload arguments. For