Changeset 36c9234 in mainline for uspace/lib/libc/generic/async.c


Ignore:
Timestamp:
2007-07-04T17:03:42Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b76f2f8
Parents:
f5b4fb9
Message:

Improve comments in async.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/async.c

    rf5b4fb9 r36c9234  
    7373 *
    7474 *
    75  * client_connection(icallid, *icall)
     75 * my_client_connection(icallid, *icall)
    7676 * {
    7777 *      if (want_refuse) {
     
    116116        link_t link;
    117117
    118         /** Fibril waiting for this message. */
     118        /** Identification of and link to the waiting fibril. */
    119119        fid_t fid;
    120120        /** If true, this fibril is currently active. */
     
    135135} amsg_t;
    136136
     137/**
     138 * Structures of this type are used to group information about a call and a
     139 * message queue link.
     140 */
    137141typedef struct {
    138142        link_t link;
     
    168172__thread connection_t *FIBRIL_connection;
    169173
    170 /** If true, it is forbidden to use async_req functions and all preemption is
    171  * disabled. */
     174/**
     175 * If true, it is forbidden to use async_req functions and all preemption is
     176 * disabled.
     177 */
    172178__thread int in_interrupt_handler;
    173179
    174180static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    175181static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
     182
     183/**
     184 * Pointer to a fibril function that will be used to handle connections.
     185 */
    176186static async_client_conn_t client_connection = default_client_connection;
     187/**
     188 * Pointer to a fibril function that will be used to handle interrupt
     189 * notifications.
     190 */
    177191static async_client_conn_t interrupt_received = default_interrupt_received;
    178192
     
    252266/** Try to route a call to an appropriate connection fibril.
    253267 *
     268 * If the proper connection fibril is found, a message with the call is added to
     269 * its message queue. If the fibril was not active, it is activated and all
     270 * timeouts are unregistered.
     271 *
     272 * @param callid        Hash of the incoming call.
     273 * @param call          Data of the incoming call.
     274 *
     275 * @return              Zero if the call doesn't match any connection.
     276 *                      One if the call was passed to the respective connection
     277 *                      fibril.
    254278 */
    255279static int route_call(ipc_callid_t callid, ipc_call_t *call)
     
    278302                conn->close_callid = callid;
    279303       
    280         /* If the call is waiting for event, run it */
     304        /* If the connection fibril is waiting for an event, activate it */
    281305        if (!conn->wdata.active) {
    282306                /* If in timeout list, remove it */
     
    315339         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    316340         *           I would never expect to find so many errors in
    317          *           compiler *($&$(*&$
     341         *           a compiler *($&$(*&$
    318342         */
    319343        conn = FIBRIL_connection;
     
    357381}
    358382
    359 /** Fibril function that gets created on new connection
     383/** Default fibril function that gets called to handle new connection.
    360384 *
    361385 * This function is defined as a weak symbol - to be redefined in user code.
     386 *
     387 * @param callid        Hash of the incoming call.
     388 * @param call          Data of the incoming call.
    362389 */
    363390static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     
    365392        ipc_answer_fast(callid, ENOENT, 0, 0);
    366393}
     394
     395/** Default fibril function that gets called to handle interrupt notifications.
     396 *
     397 * @param callid        Hash of the incoming call.
     398 * @param call          Data of the incoming call.
     399 */
    367400static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    368401{
     
    371404/** Wrapper for client connection fibril.
    372405 *
    373  * When new connection arrives, a fibril with this implementing function is
     406 * When a new connection arrives, a fibril with this implementing function is
    374407 * created. It calls client_connection() and does the final cleanup.
    375408 *
    376  * @param arg           Connection structure pointer
     409 * @param arg           Connection structure pointer.
    377410 *
    378411 * @return              Always zero.
     
    389422            &FIBRIL_connection->call);
    390423       
    391         /* Remove myself from connection hash table */
     424        /* Remove myself from the connection hash table */
    392425        futex_down(&async_futex);
    393426        key = FIBRIL_connection->in_phone_hash;
     
    395428        futex_up(&async_futex);
    396429       
    397         /* Answer all remaining messages with ehangup */
     430        /* Answer all remaining messages with EHANGUP */
    398431        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    399432                msg = list_get_instance(FIBRIL_connection->msg_queue.next,
     
    417450 * particular fibrils.
    418451 *
    419  * @param in_phone_hash Identification of the incoming connection
    420  * @param callid        Callid of the IPC_M_CONNECT_ME_TO packet
    421  * @param call          Call data of the opening packet
    422  * @param cfibril       Fibril function that should be called upon
    423  *                      opening the connection
    424  * @return              New fibril id.
     452 * @param in_phone_hash Identification of the incoming connection.
     453 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     454 * @param call          Call data of the opening call.
     455 * @param cfibril       Fibril function that should be called upon opening the
     456 *                      connection.
     457 *
     458 * @return              New fibril id or NULL on failure.
    425459 */
    426460fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
     
    441475        if (call)
    442476                conn->call = *call;
    443         conn->wdata.active = 1; /* We will activate it asap */
     477        conn->wdata.active = 1; /* We will activate the fibril ASAP */
    444478        conn->cfibril = cfibril;
    445479
     
    450484                return NULL;
    451485        }
    452         /* Add connection to hash table */
     486        /* Add connection to the connection hash table */
    453487        key = conn->in_phone_hash;
    454488        futex_down(&async_futex);
     
    461495}
    462496
    463 /** Handle a call that was received. */
     497/** Handle a call that was received.
     498 *
     499 * If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created.
     500 * Otherwise the call is routed to its connection fibril.
     501 *
     502 * @param callid        Hash of the incoming call.
     503 * @param call          Data of the incoming call.
     504 */
    464505static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    465506{
     
    480521        }
    481522
    482         /* Try to route call through connection tables */
     523        /* Try to route the call through the connection hash table */
    483524        if (route_call(callid, call))
    484525                return;
     
    495536        link_t *cur;
    496537
    497         gettimeofday(&tv,NULL);
     538        gettimeofday(&tv, NULL);
    498539        futex_down(&async_futex);
    499540
     
    507548                waiter->inlist = 0;
    508549                waiter->timedout = 1;
    509                 /* Redundant condition? The fibril should not
    510                  * be active when it gets here.
     550                /*
     551                 * Redundant condition?
     552                 * The fibril should not be active when it gets here.
    511553                 */
    512554                if (!waiter->active) {
     
    519561}
    520562
    521 /** Endless loop dispatching incoming calls and answers */
     563/** Endless loop dispatching incoming calls and answers.
     564 *
     565 * @return              Never returns.
     566 */
    522567static int async_manager_worker(void)
    523568{
     
    531576                if (fibril_schedule_next_adv(FIBRIL_FROM_MANAGER)) {
    532577                        futex_up(&async_futex);
    533                         /* async_futex is always held
    534                          * when entering manager fibril
     578                        /*
     579                         * async_futex is always held when entering a manager
     580                         * fibril.
    535581                         */
    536582                        continue;
     
    568614}
    569615
    570 /** Function to start async_manager as a standalone fibril. 
     616/** Function to start async_manager as a standalone fibril.
    571617 *
    572  * When more kernel threads are used, one async manager should
    573  * exist per thread.
     618 * When more kernel threads are used, one async manager should exist per thread.
     619 *
     620 * @param arg           Unused.
     621 *
     622 * @return              Never returns.
    574623 */
    575624static int async_manager_fibril(void *arg)
    576625{
    577626        futex_up(&async_futex);
    578         /* async_futex is always locked when entering
    579          * manager */
     627        /*
     628         * async_futex is always locked when entering manager
     629         */
    580630        async_manager_worker();
    581631       
     
    583633}
    584634
    585 /** Add one manager to manager list */
     635/** Add one manager to manager list. */
    586636void async_create_manager(void)
    587637{
     
    598648}
    599649
    600 /** Initialize internal structures needed for async manager */
     650/** Initialize the async framework.
     651 *
     652 * @return              Zero on success or an error code.
     653 */
    601654int _async_init(void)
    602655{
     
    610663}
    611664
    612 /** IPC handler for messages in async framework
    613  *
    614  * Notify the fibril which is waiting for this message, that it arrived
     665/** Reply received callback.
     666 *
     667 * This function is called whenever a reply for an asynchronous message sent out
     668 * by the asynchronous framework is received.
     669 *
     670 * Notify the fibril which is waiting for this message that it has arrived.
     671 *
     672 * @param private       Pointer to the asynchronous message record.
     673 * @param retval        Value returned in the answer.
     674 * @param data          Call data of the answer.
    615675 */
    616676static void reply_received(void *private, int retval, ipc_call_t *data)
     
    621681
    622682        futex_down(&async_futex);
    623         /* Copy data after futex_down, just in case the
    624          * call was detached
    625          */
     683        /* Copy data after futex_down, just in case the call was detached */
    626684        if (msg->dataptr)
    627685                *msg->dataptr = *data;
     
    632690                list_remove(&msg->wdata.link);
    633691        msg->done = 1;
    634         if (! msg->wdata.active) {
     692        if (!msg->wdata.active) {
    635693                msg->wdata.active = 1;
    636694                fibril_add_ready(msg->wdata.fid);
     
    639697}
    640698
    641 /** Send message and return id of the sent message
    642  *
    643  * The return value can be used as input for async_wait() to wait
    644  * for completion.
     699/** Send message and return id of the sent message.
     700 *
     701 * The return value can be used as input for async_wait() to wait for
     702 * completion.
     703 *
     704 * @param phoneid       Handle of the phone that will be used for the send.
     705 * @param method        Service-defined method.
     706 * @param arg1          Service-defined payload argument.
     707 * @param arg2          Service-defined payload argument.
     708 * @param dataptr       If non-NULL, storage where the reply data will be
     709 *                      stored.
     710 *
     711 * @return              Hash of the sent message.
    645712 */
    646713aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     
    659726        msg->dataptr = dataptr;
    660727
    661         msg->wdata.active = 1; /* We may sleep in next method, but it
    662                                 * will use it's own mechanism */
     728        /* We may sleep in the next method, but it will use its own mechanism */
     729        msg->wdata.active = 1;
     730                               
    663731        ipc_call_async_2(phoneid, method, arg1, arg2, msg, reply_received, 1);
    664732
     
    668736/** Send message and return id of the sent message
    669737 *
    670  * The return value can be used as input for async_wait() to wait
    671  * for completion.
     738 * The return value can be used as input for async_wait() to wait for
     739 * completion.
     740 *
     741 * @param phoneid       Handle of the phone that will be used for the send.
     742 * @param method        Service-defined method.
     743 * @param arg1          Service-defined payload argument.
     744 * @param arg2          Service-defined payload argument.
     745 * @param arg3          Service-defined payload argument.
     746 * @param dataptr       If non-NULL, storage where the reply data will be
     747 *                      stored.
     748 *
     749 * @return              Hash of the sent message.
    672750 */
    673751aid_t async_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     
    677755
    678756        if (in_interrupt_handler) {
    679                 printf("Cannot send asynchronous request in interrupt handler.\n");
     757                printf("Cannot send asynchronous request in interrupt "
     758                    "handler.\n");
    680759                _exit(1);
    681760        }
     
    685764        msg->dataptr = dataptr;
    686765
    687         msg->wdata.active = 1; /* We may sleep in next method, but it
    688                                 * will use it's own mechanism */
     766        /* We may sleep in next method, but it will use its own mechanism */
     767        msg->wdata.active = 1;
     768                               
    689769        ipc_call_async_3(phoneid, method, arg1, arg2, arg3, msg, reply_received,
    690770            1);
     
    693773}
    694774
    695 /** Wait for a message sent by async framework
    696  *
    697  * @param amsgid        Message ID to wait for
    698  * @param retval        Pointer to variable where will be stored retval of the
    699  *                      answered message. If NULL, it is ignored.
     775/** Wait for a message sent by the async framework.
     776 *
     777 * @param amsgid        Hash of the message to wait for.
     778 * @param retval        Pointer to storage where the retval of the answer will
     779 *                      be stored.
    700780 */
    701781void async_wait_for(aid_t amsgid, ipcarg_t *retval)
     
    712792        msg->wdata.active = 0;
    713793        msg->wdata.inlist = 0;
    714         /* Leave locked async_futex when entering this function */
     794        /* Leave the async_futex locked when entering this function */
    715795        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
    716796        /* futex is up automatically after fibril_schedule_next...*/
     
    721801}
    722802
    723 /** Wait for a message sent by async framework with timeout
    724  *
    725  * @param amsgid Message ID to wait for
    726  * @param retval Pointer to variable where will be stored retval
    727  *               of the answered message. If NULL, it is ignored.
    728  * @param timeout Timeout in usecs
    729  * @return 0 on success, ETIMEOUT if timeout expired
    730  *
     803/** Wait for a message sent by the async framework, timeout variant.
     804 *
     805 * @param amsgid        Hash of the message to wait for.
     806 * @param retval        Pointer to storage where the retval of the answer will
     807 *                      be stored.
     808 * @param timeout       Timeout in microseconds.
     809 *
     810 * @return              Zero on success, ETIMEOUT if the timeout has expired.
    731811 */
    732812int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout)
     
    751831        insert_timeout(&msg->wdata);
    752832
    753         /* Leave locked async_futex when entering this function */
     833        /* Leave the async_futex locked when entering this function */
    754834        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
    755835        /* futex is up automatically after fibril_schedule_next...*/
     
    766846}
    767847
    768 /** Wait specified time, but in the meantime handle incoming events
    769  *
    770  * @param timeout Time in microseconds to wait
     848/** Wait for specified time.
     849 *
     850 * The current fibril is suspended but the thread continues to execute.
     851 *
     852 * @param timeout       Duration of the wait in microseconds.
    771853 */
    772854void async_usleep(suseconds_t timeout)
     
    791873        futex_down(&async_futex);
    792874        insert_timeout(&msg->wdata);
    793         /* Leave locked the async_futex when entering this function */
     875        /* Leave the async_futex locked when entering this function */
    794876        fibril_schedule_next_adv(FIBRIL_TO_MANAGER);
    795877        /* futex is up automatically after fibril_schedule_next_adv()...*/
     
    797879}
    798880
    799 /** Set function that is called when IPC_M_CONNECT_ME_TO is received.
    800  *
    801  * @param conn Function that will form a new fibril.
     881/** Setter for client_connection function pointer.
     882 *
     883 * @param conn          Function that will implement a new connection fibril.
    802884 */
    803885void async_set_client_connection(async_client_conn_t conn)
     
    805887        client_connection = conn;
    806888}
     889
     890/** Setter for interrupt_received function pointer.
     891 *
     892 * @param conn          Function that will implement a new interrupt
     893 *                      notification fibril.
     894 */
    807895void async_set_interrupt_received(async_client_conn_t conn)
    808896{
     
    826914/** @}
    827915 */
     916
Note: See TracChangeset for help on using the changeset viewer.