Changeset bf75e3cb in mainline


Ignore:
Timestamp:
2011-01-26T20:22:21Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4e7d3dd, 5b7a107, 875c629
Parents:
a0ce870 (diff), 4fe94c66 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/fs.

Highlights of the merge:

  • the kernel signs each call by the sender's task hash
  • async framework tracks and reference counts connections from the same client task
  • VFS associates the table of open files with the client task rather than with a single connection
  • VFS libc client code now uses async sessions to support parallel requests
  • vfs_file_get() now explicitly adds a reference on the file structure and the newly introduced vfs_file_put() drops it
Files:
36 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    ra0ce870 rbf75e3cb  
    165165 *                       error is sent back to caller. Otherwise
    166166 *                       the call is accepted and the response is sent back.
    167  *                     - the allocated phoneid is passed to userspace
     167 *                     - the hash of the client task is passed to userspace
     168 *                       (on the receiving side) as ARG4 of the call.
     169 *                     - the hash of the allocated phone is passed to userspace
    168170 *                       (on the receiving side) as ARG5 of the call.
    169171 *
     
    319321typedef struct {
    320322        sysarg_t args[IPC_CALL_LEN];
     323        /** Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME. */
     324        struct task *task;
     325        /** Phone which made or last masqueraded this call. */
    321326        phone_t *phone;
    322327} ipc_data_t;
  • kernel/generic/src/ipc/ipc.c

    ra0ce870 rbf75e3cb  
    295295                atomic_inc(&phone->active_calls);
    296296                call->data.phone = phone;
     297                call->data.task = TASK;
    297298        }
    298299       
     
    406407                        call->caller_phone = call->data.phone;
    407408                call->data.phone = newphone;
     409                call->data.task = TASK;
    408410        }
    409411       
  • kernel/generic/src/ipc/sysipc.c

    ra0ce870 rbf75e3cb  
    248248                        /* The connection was accepted */
    249249                        phone_connect(phoneid, &answer->sender->answerbox);
     250                        /* Set 'task hash' as arg4 of response */
     251                        IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
    250252                        /* Set 'phone hash' as arg5 of response */
    251253                        IPC_SET_ARG5(answer->data,
  • uspace/lib/c/generic/async.c

    ra0ce870 rbf75e3cb  
    134134
    135135typedef struct {
     136        sysarg_t in_task_hash;
     137        link_t link;
     138        int refcnt;
     139        void *data;
     140} client_t;
     141
     142typedef struct {
    136143        awaiter_t wdata;
    137144       
     
    139146        link_t link;
    140147       
     148        /** Incoming client task hash. */
     149        sysarg_t in_task_hash;
    141150        /** Incoming phone hash. */
    142151        sysarg_t in_phone_hash;
    143152       
     153        /** Link to the client tracking structure. */
     154        client_t *client;
     155
    144156        /** Messages that should be delivered to this fibril. */
    145157        link_t msg_queue;
     
    160172fibril_local connection_t *FIBRIL_connection;
    161173
     174static void *default_client_data_constructor(void)
     175{
     176        return NULL;
     177}
     178
     179static void default_client_data_destructor(void *data)
     180{
     181}
     182
     183static async_client_data_ctor_t async_client_data_create =
     184    default_client_data_constructor;
     185static async_client_data_dtor_t async_client_data_destroy =
     186    default_client_data_destructor;
     187
     188void async_set_client_data_constructor(async_client_data_ctor_t ctor)
     189{
     190        async_client_data_create = ctor;
     191}
     192
     193void async_set_client_data_destructor(async_client_data_dtor_t dtor)
     194{
     195        async_client_data_destroy = dtor;
     196}
     197
     198void *async_client_data_get(void)
     199{
     200        assert(FIBRIL_connection);
     201
     202        return FIBRIL_connection->client->data;
     203}
     204
    162205static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    163206static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
     
    174217static async_client_conn_t interrupt_received = default_interrupt_received;
    175218
     219static hash_table_t client_hash_table;
    176220static hash_table_t conn_hash_table;
    177221static LIST_INITIALIZE(timeout_list);
    178222
    179 #define CONN_HASH_TABLE_CHAINS  32
     223#define CLIENT_HASH_TABLE_BUCKETS       32
     224#define CONN_HASH_TABLE_BUCKETS         32
     225
     226static hash_index_t client_hash(unsigned long *key)
     227{
     228        assert(key);
     229        return (((*key) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
     230}
     231
     232static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
     233{
     234        client_t *cl = hash_table_get_instance(item, client_t, link);
     235        return (key[0] == cl->in_task_hash);
     236}
     237
     238static void client_remove(link_t *item)
     239{
     240}
     241
     242/** Operations for the client hash table. */
     243static hash_table_operations_t client_hash_table_ops = {
     244        .hash = client_hash,
     245        .compare = client_compare,
     246        .remove_callback = client_remove
     247};
    180248
    181249/** Compute hash into the connection hash table based on the source phone hash.
     
    189257{
    190258        assert(key);
    191         return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
     259        return (((*key) >> 4) % CONN_HASH_TABLE_BUCKETS);
    192260}
    193261
     
    480548static int connection_fibril(void *arg)
    481549{
     550        unsigned long key;
     551        client_t *cl;
     552        link_t *lnk;
     553        bool destroy = false;
     554
    482555        /*
    483          * Setup fibril-local connection pointer and call client_connection().
    484          *
     556         * Setup fibril-local connection pointer.
    485557         */
    486558        FIBRIL_connection = (connection_t *) arg;
     559
     560        /*
     561         * Add our reference for the current connection in the client task
     562         * tracking structure. If this is the first reference, create and
     563         * hash in a new tracking structure.
     564         */
     565        futex_down(&async_futex);
     566        key = FIBRIL_connection->in_task_hash;
     567        lnk = hash_table_find(&client_hash_table, &key);
     568        if (lnk) {
     569                cl = hash_table_get_instance(lnk, client_t, link);
     570                cl->refcnt++;
     571        } else {
     572                cl = malloc(sizeof(client_t));
     573                if (!cl) {
     574                        ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
     575                        futex_up(&async_futex);
     576                        return 0;
     577                }
     578                cl->in_task_hash = FIBRIL_connection->in_task_hash;
     579                async_serialize_start();
     580                cl->data = async_client_data_create();
     581                async_serialize_end();
     582                cl->refcnt = 1;
     583                hash_table_insert(&client_hash_table, &key, &cl->link);
     584        }
     585        futex_up(&async_futex);
     586
     587        FIBRIL_connection->client = cl;
     588
     589        /*
     590         * Call the connection handler function.
     591         */
    487592        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    488593            &FIBRIL_connection->call);
    489594       
    490         /* Remove myself from the connection hash table */
     595        /*
     596         * Remove the reference for this client task connection.
     597         */
    491598        futex_down(&async_futex);
    492         unsigned long key = FIBRIL_connection->in_phone_hash;
     599        if (--cl->refcnt == 0) {
     600                hash_table_remove(&client_hash_table, &key, 1);
     601                destroy = true;
     602        }
     603        futex_up(&async_futex);
     604
     605        if (destroy) {
     606                if (cl->data)
     607                        async_client_data_destroy(cl->data);
     608                free(cl);
     609        }
     610
     611        /*
     612         * Remove myself from the connection hash table.
     613         */
     614        futex_down(&async_futex);
     615        key = FIBRIL_connection->in_phone_hash;
    493616        hash_table_remove(&conn_hash_table, &key, 1);
    494617        futex_up(&async_futex);
    495618       
    496         /* Answer all remaining messages with EHANGUP */
     619        /*
     620         * Answer all remaining messages with EHANGUP.
     621         */
    497622        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    498623                msg_t *msg;
     
    505630        }
    506631       
     632        /*
     633         * If the connection was hung-up, answer the last call,
     634         * i.e. IPC_M_PHONE_HUNGUP.
     635         */
    507636        if (FIBRIL_connection->close_callid)
    508637                ipc_answer_0(FIBRIL_connection->close_callid, EOK);
     
    517646 * particular fibrils.
    518647 *
     648 * @param in_task_hash  Identification of the incoming connection.
    519649 * @param in_phone_hash Identification of the incoming connection.
    520650 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    529659 *
    530660 */
    531 fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
    532     ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
     661fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     662    ipc_callid_t callid, ipc_call_t *call,
     663    void (*cfibril)(ipc_callid_t, ipc_call_t *))
    533664{
    534665        connection_t *conn = malloc(sizeof(*conn));
     
    539670        }
    540671       
     672        conn->in_task_hash = in_task_hash;
    541673        conn->in_phone_hash = in_phone_hash;
    542674        list_initialize(&conn->msg_queue);
     
    592724        case IPC_M_CONNECT_ME_TO:
    593725                /* Open new connection with fibril etc. */
    594                 async_new_connection(IPC_GET_ARG5(*call), callid, call,
    595                     client_connection);
     726                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
     727                    callid, call, client_connection);
    596728                goto out;
    597729        }
     
    744876int __async_init(void)
    745877{
    746         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
    747             &conn_hash_table_ops)) {
    748                 printf("%s: Cannot create async hash table\n", "libc");
     878        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
     879            &client_hash_table_ops) || !hash_table_create(&conn_hash_table,
     880            CONN_HASH_TABLE_BUCKETS, 1, &conn_hash_table_ops)) {
    749881                return ENOMEM;
    750882        }
  • uspace/lib/c/generic/devman.c

    ra0ce870 rbf75e3cb  
    116116        async_set_client_connection(conn);
    117117       
    118         sysarg_t callback_phonehash;
    119         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     118        ipc_connect_to_me(phone, 0, 0, 0, NULL, NULL);
    120119        async_wait_for(req, &retval);
    121120       
  • uspace/lib/c/generic/devmap.c

    ra0ce870 rbf75e3cb  
    116116        async_set_client_connection(conn);
    117117       
    118         sysarg_t callback_phonehash;
    119         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     118        ipc_connect_to_me(phone, 0, 0, 0, NULL, NULL);
    120119        async_wait_for(req, &retval);
    121120       
  • uspace/lib/c/generic/ipc.c

    ra0ce870 rbf75e3cb  
    578578 * @param arg2          Service-defined argument.
    579579 * @param arg3          Service-defined argument.
    580  * @param phonehash     Storage where the library will store an opaque
     580 * @param taskhash      Storage where the kernel will store an opaque
     581 *                      identifier of the client task.
     582 * @param phonehash     Storage where the kernel will store an opaque
    581583 *                      identifier of the phone that will be used for incoming
    582584 *                      calls. This identifier can be used for connection
     
    586588 */
    587589int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
    588     sysarg_t *phonehash)
     590    sysarg_t *taskhash, sysarg_t *phonehash)
    589591{
    590592        return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    591             arg3, NULL, NULL, NULL, NULL, phonehash);
     593            arg3, NULL, NULL, NULL, taskhash, phonehash);
    592594}
    593595
  • uspace/lib/c/generic/net/modules.c

    ra0ce870 rbf75e3cb  
    143143        if (phone >= 0) {
    144144                /* Request the bidirectional connection */
     145                sysarg_t taskhash;
    145146                sysarg_t phonehash;
    146147               
    147                 rc = ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash);
     148                rc = ipc_connect_to_me(phone, arg1, arg2, arg3, &taskhash,
     149                    &phonehash);
    148150                if (rc != EOK) {
    149151                        ipc_hangup(phone);
    150152                        return rc;
    151153                }
    152                 async_new_connection(phonehash, 0, NULL, client_receiver);
     154                async_new_connection(taskhash, phonehash, 0, NULL,
     155                    client_receiver);
    153156        }
    154157       
  • uspace/lib/c/generic/vfs/vfs.c

    ra0ce870 rbf75e3cb  
    4646#include <ipc/services.h>
    4747#include <async.h>
    48 #include <atomic.h>
    49 #include <futex.h>
     48#include <fibril_synch.h>
    5049#include <errno.h>
     50#include <assert.h>
    5151#include <str.h>
    5252#include <devmap.h>
     
    5454#include <ipc/devmap.h>
    5555
     56static async_sess_t vfs_session;
     57
     58static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    5659static int vfs_phone = -1;
    57 static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
    58 static futex_t cwd_futex = FUTEX_INITIALIZER;
     60
     61static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
    5962
    6063static int cwd_fd = -1;
     
    6770        char *ncwd_path_nc;
    6871
    69         futex_down(&cwd_futex);
     72        fibril_mutex_lock(&cwd_mutex);
    7073        size_t size = str_size(path);
    7174        if (*path != '/') {
    7275                if (!cwd_path) {
    73                         futex_up(&cwd_futex);
     76                        fibril_mutex_unlock(&cwd_mutex);
    7477                        return NULL;
    7578                }
    7679                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    7780                if (!ncwd_path_nc) {
    78                         futex_up(&cwd_futex);
     81                        fibril_mutex_unlock(&cwd_mutex);
    7982                        return NULL;
    8083                }
     
    8588                ncwd_path_nc = malloc(size + 1);
    8689                if (!ncwd_path_nc) {
    87                         futex_up(&cwd_futex);
     90                        fibril_mutex_unlock(&cwd_mutex);
    8891                        return NULL;
    8992                }
     
    9396        ncwd_path = canonify(ncwd_path_nc, retlen);
    9497        if (!ncwd_path) {
    95                 futex_up(&cwd_futex);
     98                fibril_mutex_unlock(&cwd_mutex);
    9699                free(ncwd_path_nc);
    97100                return NULL;
     
    105108        free(ncwd_path_nc);
    106109        if (!ncwd_path) {
    107                 futex_up(&cwd_futex);
     110                fibril_mutex_unlock(&cwd_mutex);
    108111                return NULL;
    109112        }
    110         futex_up(&cwd_futex);
     113        fibril_mutex_unlock(&cwd_mutex);
    111114        return ncwd_path;
    112115}
    113116
     117/** Connect to VFS service and create session. */
    114118static void vfs_connect(void)
    115119{
    116         while (vfs_phone < 0)
    117                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
     120        while (vfs_phone < 0) {
     121                vfs_phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_VFS,
     122                    0, 0);
     123        }
     124       
     125        async_session_create(&vfs_session, vfs_phone, 0);
     126}
     127
     128/** Start an async exchange on the VFS session.
     129 *
     130 * @return              New phone to be used during the exchange.
     131 */
     132static int vfs_exchange_begin(void)
     133{
     134        fibril_mutex_lock(&vfs_phone_mutex);
     135        if (vfs_phone < 0)
     136                vfs_connect();
     137        fibril_mutex_unlock(&vfs_phone_mutex);
     138
     139        return async_exchange_begin(&vfs_session);
     140}
     141
     142/** End an async exchange on the VFS session.
     143 *
     144 * @param phone         Phone used during the exchange.
     145 */
     146static void vfs_exchange_end(int phone)
     147{
     148        async_exchange_end(&vfs_session, phone);
    118149}
    119150
     
    154185        }
    155186       
    156         futex_down(&vfs_phone_futex);
    157         async_serialize_start();
    158         vfs_connect();
    159        
     187        int vfs_phone = vfs_exchange_begin();
     188
    160189        sysarg_t rc_orig;
    161190        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    162191        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    163192        if (rc != EOK) {
    164                 async_wait_for(req, &rc_orig);
    165                 async_serialize_end();
    166                 futex_up(&vfs_phone_futex);
     193                vfs_exchange_end(vfs_phone);
    167194                free(mpa);
     195                async_wait_for(req, &rc_orig);
    168196               
    169197                if (null_id != -1)
     
    178206        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    179207        if (rc != EOK) {
    180                 async_wait_for(req, &rc_orig);
    181                 async_serialize_end();
    182                 futex_up(&vfs_phone_futex);
     208                vfs_exchange_end(vfs_phone);
    183209                free(mpa);
     210                async_wait_for(req, &rc_orig);
    184211               
    185212                if (null_id != -1)
     
    194221        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    195222        if (rc != EOK) {
    196                 async_wait_for(req, &rc_orig);
    197                 async_serialize_end();
    198                 futex_up(&vfs_phone_futex);
     223                vfs_exchange_end(vfs_phone);
    199224                free(mpa);
     225                async_wait_for(req, &rc_orig);
    200226               
    201227                if (null_id != -1)
     
    211237        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    212238        if (rc != EOK) {
    213                 async_wait_for(req, &rc_orig);
    214                 async_serialize_end();
    215                 futex_up(&vfs_phone_futex);
     239                vfs_exchange_end(vfs_phone);
    216240                free(mpa);
     241                async_wait_for(req, &rc_orig);
    217242               
    218243                if (null_id != -1)
     
    225250        }
    226251       
    227         async_wait_for(req, &rc);
    228         async_serialize_end();
    229         futex_up(&vfs_phone_futex);
     252        vfs_exchange_end(vfs_phone);
    230253        free(mpa);
     254        async_wait_for(req, &rc);
    231255       
    232256        if ((rc != EOK) && (null_id != -1))
     
    248272                return ENOMEM;
    249273       
    250         futex_down(&vfs_phone_futex);
    251         async_serialize_start();
    252         vfs_connect();
     274        int vfs_phone = vfs_exchange_begin();
    253275       
    254276        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    255277        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    256278        if (rc != EOK) {
    257                 async_wait_for(req, &rc_orig);
    258                 async_serialize_end();
    259                 futex_up(&vfs_phone_futex);
     279                vfs_exchange_end(vfs_phone);
    260280                free(mpa);
    261                 if (rc_orig == EOK)
    262                         return (int) rc;
    263                 else
    264                         return (int) rc_orig;
    265         }
    266        
    267 
    268         async_wait_for(req, &rc);
    269         async_serialize_end();
    270         futex_up(&vfs_phone_futex);
     281                async_wait_for(req, &rc_orig);
     282                if (rc_orig == EOK)
     283                        return (int) rc;
     284                else
     285                        return (int) rc_orig;
     286        }
     287       
     288
     289        vfs_exchange_end(vfs_phone);
    271290        free(mpa);
     291        async_wait_for(req, &rc);
    272292       
    273293        return (int) rc;
     
    276296static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    277297{
    278         futex_down(&vfs_phone_futex);
    279         async_serialize_start();
    280         vfs_connect();
     298        int vfs_phone = vfs_exchange_begin();
    281299       
    282300        ipc_call_t answer;
     
    285303       
    286304        if (rc != EOK) {
     305                vfs_exchange_end(vfs_phone);
     306
    287307                sysarg_t rc_orig;
    288308                async_wait_for(req, &rc_orig);
    289309               
    290                 async_serialize_end();
    291                 futex_up(&vfs_phone_futex);
    292                
    293                 if (rc_orig == EOK)
    294                         return (int) rc;
    295                 else
    296                         return (int) rc_orig;
    297         }
    298        
    299         async_wait_for(req, &rc);
    300         async_serialize_end();
    301         futex_up(&vfs_phone_futex);
     310                if (rc_orig == EOK)
     311                        return (int) rc;
     312                else
     313                        return (int) rc_orig;
     314        }
     315       
     316        vfs_exchange_end(vfs_phone);
     317        async_wait_for(req, &rc);
    302318       
    303319        if (rc != EOK)
     
    322338int open_node(fdi_node_t *node, int oflag)
    323339{
    324         futex_down(&vfs_phone_futex);
    325         async_serialize_start();
    326         vfs_connect();
     340        int vfs_phone = vfs_exchange_begin();
    327341       
    328342        ipc_call_t answer;
     
    330344            node->devmap_handle, node->index, oflag, &answer);
    331345       
    332         sysarg_t rc;
    333         async_wait_for(req, &rc);
    334         async_serialize_end();
    335         futex_up(&vfs_phone_futex);
     346        vfs_exchange_end(vfs_phone);
     347
     348        sysarg_t rc;
     349        async_wait_for(req, &rc);
    336350       
    337351        if (rc != EOK)
     
    345359        sysarg_t rc;
    346360       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
     361        int vfs_phone = vfs_exchange_begin();
    350362       
    351363        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    352364       
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
     365        vfs_exchange_end(vfs_phone);
    355366       
    356367        return (int)rc;
     
    363374        aid_t req;
    364375
    365         futex_down(&vfs_phone_futex);
    366         async_serialize_start();
    367         vfs_connect();
     376        int vfs_phone = vfs_exchange_begin();
    368377       
    369378        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    370379        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371380        if (rc != EOK) {
     381                vfs_exchange_end(vfs_phone);
     382
    372383                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     384                async_wait_for(req, &rc_orig);
     385
    377386                if (rc_orig == EOK)
    378387                        return (ssize_t) rc;
     
    380389                        return (ssize_t) rc_orig;
    381390        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     391        vfs_exchange_end(vfs_phone);
     392        async_wait_for(req, &rc);
    385393        if (rc == EOK)
    386394                return (ssize_t) IPC_GET_ARG1(answer);
     
    395403        aid_t req;
    396404
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     405        int vfs_phone = vfs_exchange_begin();
    400406       
    401407        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402408        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403409        if (rc != EOK) {
     410                vfs_exchange_end(vfs_phone);
     411
    404412                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     413                async_wait_for(req, &rc_orig);
     414
    409415                if (rc_orig == EOK)
    410416                        return (ssize_t) rc;
     
    412418                        return (ssize_t) rc_orig;
    413419        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     420        vfs_exchange_end(vfs_phone);
     421        async_wait_for(req, &rc);
    417422        if (rc == EOK)
    418423                return (ssize_t) IPC_GET_ARG1(answer);
     
    423428int fsync(int fildes)
    424429{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     430        int vfs_phone = vfs_exchange_begin();
    428431       
    429432        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430433       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     434        vfs_exchange_end(vfs_phone);
    433435       
    434436        return (int) rc;
     
    437439off64_t lseek(int fildes, off64_t offset, int whence)
    438440{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     441        int vfs_phone = vfs_exchange_begin();
    442442       
    443443        sysarg_t newoff_lo;
     
    447447            &newoff_lo, &newoff_hi);
    448448       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     449        vfs_exchange_end(vfs_phone);
    451450       
    452451        if (rc != EOK)
     
    460459        sysarg_t rc;
    461460       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     461        int vfs_phone = vfs_exchange_begin();
    465462       
    466463        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467464            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     465        vfs_exchange_end(vfs_phone);
    470466       
    471467        return (int) rc;
     
    477473        aid_t req;
    478474
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     475        int vfs_phone = vfs_exchange_begin();
    482476       
    483477        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484478        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485479        if (rc != EOK) {
     480                vfs_exchange_end(vfs_phone);
     481
    486482                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     483                async_wait_for(req, &rc_orig);
     484
    491485                if (rc_orig == EOK)
    492486                        return (ssize_t) rc;
     
    494488                        return (ssize_t) rc_orig;
    495489        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     490        vfs_exchange_end(vfs_phone);
     491        async_wait_for(req, &rc);
    499492
    500493        return rc;
     
    512505                return ENOMEM;
    513506       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     507        int vfs_phone = vfs_exchange_begin();
    517508       
    518509        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519510        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520511        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     512                vfs_exchange_end(vfs_phone);
    524513                free(pa);
     514                async_wait_for(req, &rc_orig);
    525515                if (rc_orig == EOK)
    526516                        return (int) rc;
     
    530520        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531521        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     522                vfs_exchange_end(vfs_phone);
    535523                free(pa);
    536                 if (rc_orig == EOK)
    537                         return (int) rc;
    538                 else
    539                         return (int) rc_orig;
    540         }
    541         async_wait_for(req, &rc);
    542         async_serialize_end();
    543         futex_up(&vfs_phone_futex);
     524                async_wait_for(req, &rc_orig);
     525                if (rc_orig == EOK)
     526                        return (int) rc;
     527                else
     528                        return (int) rc_orig;
     529        }
     530        vfs_exchange_end(vfs_phone);
    544531        free(pa);
     532        async_wait_for(req, &rc);
    545533        return rc;
    546534}
     
    601589                return ENOMEM;
    602590       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     591        int vfs_phone = vfs_exchange_begin();
    606592       
    607593        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608594        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609595        if (rc != EOK) {
     596                vfs_exchange_end(vfs_phone);
     597                free(pa);
     598
    610599                sysarg_t rc_orig;
    611        
    612                 async_wait_for(req, &rc_orig);
    613                 async_serialize_end();
    614                 futex_up(&vfs_phone_futex);
    615                 free(pa);
    616                 if (rc_orig == EOK)
    617                         return (int) rc;
    618                 else
    619                         return (int) rc_orig;
    620         }
    621         async_wait_for(req, &rc);
    622         async_serialize_end();
    623         futex_up(&vfs_phone_futex);
     600                async_wait_for(req, &rc_orig);
     601
     602                if (rc_orig == EOK)
     603                        return (int) rc;
     604                else
     605                        return (int) rc_orig;
     606        }
     607        vfs_exchange_end(vfs_phone);
    624608        free(pa);
     609        async_wait_for(req, &rc);
    625610        return rc;
    626611}
     
    636621                return ENOMEM;
    637622
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     623        int vfs_phone = vfs_exchange_begin();
    641624       
    642625        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643626        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644627        if (rc != EOK) {
     628                vfs_exchange_end(vfs_phone);
     629                free(pa);
     630
    645631                sysarg_t rc_orig;
    646 
    647                 async_wait_for(req, &rc_orig);
    648                 async_serialize_end();
    649                 futex_up(&vfs_phone_futex);
    650                 free(pa);
    651                 if (rc_orig == EOK)
    652                         return (int) rc;
    653                 else
    654                         return (int) rc_orig;
    655         }
    656         async_wait_for(req, &rc);
    657         async_serialize_end();
    658         futex_up(&vfs_phone_futex);
     632                async_wait_for(req, &rc_orig);
     633
     634                if (rc_orig == EOK)
     635                        return (int) rc;
     636                else
     637                        return (int) rc_orig;
     638        }
     639        vfs_exchange_end(vfs_phone);
    659640        free(pa);
     641        async_wait_for(req, &rc);
    660642        return rc;
    661643}
     
    689671        }
    690672
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     673        int vfs_phone = vfs_exchange_begin();
    694674       
    695675        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696676        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697677        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     678                vfs_exchange_end(vfs_phone);
    701679                free(olda);
    702680                free(newa);
     681                async_wait_for(req, &rc_orig);
    703682                if (rc_orig == EOK)
    704683                        return (int) rc;
     
    708687        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709688        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     689                vfs_exchange_end(vfs_phone);
    713690                free(olda);
    714691                free(newa);
    715                 if (rc_orig == EOK)
    716                         return (int) rc;
    717                 else
    718                         return (int) rc_orig;
    719         }
    720         async_wait_for(req, &rc);
    721         async_serialize_end();
    722         futex_up(&vfs_phone_futex);
     692                async_wait_for(req, &rc_orig);
     693                if (rc_orig == EOK)
     694                        return (int) rc;
     695                else
     696                        return (int) rc_orig;
     697        }
     698        vfs_exchange_end(vfs_phone);
    723699        free(olda);
    724700        free(newa);
     701        async_wait_for(req, &rc);
    725702        return rc;
    726703}
     
    740717        }
    741718       
    742         futex_down(&cwd_futex);
     719        fibril_mutex_lock(&cwd_mutex);
    743720       
    744721        if (cwd_fd >= 0)
     
    753730        cwd_size = abs_size;
    754731       
    755         futex_up(&cwd_futex);
     732        fibril_mutex_unlock(&cwd_mutex);
    756733        return EOK;
    757734}
     
    762739                return NULL;
    763740       
    764         futex_down(&cwd_futex);
     741        fibril_mutex_lock(&cwd_mutex);
    765742       
    766743        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     744                fibril_mutex_unlock(&cwd_mutex);
    768745                return NULL;
    769746        }
    770747       
    771748        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     749        fibril_mutex_unlock(&cwd_mutex);
    773750       
    774751        return buf;
     
    806783int dup2(int oldfd, int newfd)
    807784{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     785        int vfs_phone = vfs_exchange_begin();
    811786       
    812787        sysarg_t ret;
    813788        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814789       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     790        vfs_exchange_end(vfs_phone);
    817791       
    818792        if (rc == EOK)
  • uspace/lib/c/include/async.h

    ra0ce870 rbf75e3cb  
    4444
    4545typedef ipc_callid_t aid_t;
    46 typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
     46
     47typedef void *(*async_client_data_ctor_t)(void);
     48typedef void (*async_client_data_dtor_t)(void *);
     49
     50typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
    4751
    4852extern atomic_t async_futex;
     
    5155
    5256extern int __async_init(void);
    53 extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
     57extern ipc_callid_t async_get_call_timeout(ipc_call_t *, suseconds_t);
    5458
    5559static inline ipc_callid_t async_get_call(ipc_call_t *data)
     
    8589            (arg5), (dataptr))
    8690
    87 extern aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    88     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr);
    89 extern aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    90     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    91     ipc_call_t *dataptr);
    92 extern void async_wait_for(aid_t amsgid, sysarg_t *result);
    93 extern int async_wait_timeout(aid_t amsgid, sysarg_t *retval,
    94     suseconds_t timeout);
    95 
    96 extern fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
    97     ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
    98 extern void async_usleep(suseconds_t timeout);
     91extern aid_t async_send_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     92    sysarg_t, ipc_call_t *);
     93extern aid_t async_send_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     94    sysarg_t, sysarg_t, ipc_call_t *);
     95extern void async_wait_for(aid_t, sysarg_t *);
     96extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
     97
     98extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
     99    ipc_call_t *, void (*)(ipc_callid_t, ipc_call_t *));
     100extern void async_usleep(suseconds_t);
    99101extern void async_create_manager(void);
    100102extern void async_destroy_manager(void);
    101103
    102 extern void async_set_client_connection(async_client_conn_t conn);
    103 extern void async_set_interrupt_received(async_client_conn_t conn);
     104extern void async_set_client_data_constructor(async_client_data_ctor_t);
     105extern void async_set_client_data_destructor(async_client_data_dtor_t);
     106
     107extern void *async_client_data_get(void);
     108
     109extern void async_set_client_connection(async_client_conn_t);
     110extern void async_set_interrupt_received(async_client_conn_t);
    104111
    105112/* Wrappers for simple communication */
     
    243250            (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
    244251
    245 extern sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    246     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    247     sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
    248 extern sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    249     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    250     sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
     252extern sysarg_t async_req_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     253    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
     254extern sysarg_t async_req_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     255    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
     256    sysarg_t *);
    251257
    252258static inline void async_serialize_start(void)
  • uspace/lib/c/include/ipc/ipc.h

    ra0ce870 rbf75e3cb  
    4646typedef struct {
    4747        sysarg_t args[IPC_CALL_LEN];
     48        sysarg_t in_task_hash;
    4849        sysarg_t in_phone_hash;
    4950} ipc_call_t;
     
    258259    sysarg_t, sysarg_t, void *, ipc_async_callback_t, int);
    259260
    260 extern int ipc_connect_to_me(int, int, int, int, sysarg_t *);
     261extern int ipc_connect_to_me(int, int, int, int, sysarg_t *, sysarg_t *);
    261262extern int ipc_connect_me_to(int, int, int, int);
    262263extern int ipc_connect_me_to_blocking(int, int, int, int);
  • uspace/lib/fs/libfs.c

    ra0ce870 rbf75e3cb  
    102102         * Ask VFS for callback connection.
    103103         */
    104         ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
     104        sysarg_t taskhash;
     105        ipc_connect_to_me(vfs_phone, 0, 0, 0, &taskhash, &reg->vfs_phonehash);
    105106       
    106107        /*
     
    131132         * Create a connection fibril to handle the callback connection.
    132133         */
    133         async_new_connection(reg->vfs_phonehash, 0, NULL, conn);
     134        async_new_connection(taskhash, reg->vfs_phonehash, 0, NULL, conn);
    134135       
    135136        /*
  • uspace/lib/net/il/il_skel.c

    ra0ce870 rbf75e3cb  
    115115                goto out;
    116116       
    117         sysarg_t phonehash;
    118         rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, &phonehash);
     117        rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
    119118        if (rc != EOK)
    120119                goto out;
  • uspace/lib/net/nil/nil_skel.c

    ra0ce870 rbf75e3cb  
    115115                goto out;
    116116       
    117         sysarg_t phonehash;
    118         rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, &phonehash);
     117        rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
    119118        if (rc != EOK)
    120119                goto out;
  • uspace/lib/net/tl/tl_skel.c

    ra0ce870 rbf75e3cb  
    117117                goto out;
    118118       
    119         sysarg_t phonehash;
    120         rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, &phonehash);
     119        rc = ipc_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
    121120        if (rc != EOK)
    122121                goto out;
  • uspace/srv/clip/clip.c

    ra0ce870 rbf75e3cb  
    183183        async_set_client_connection(clip_connection);
    184184       
    185         sysarg_t phonead;
    186         if (ipc_connect_to_me(PHONE_NS, SERVICE_CLIPBOARD, 0, 0, &phonead) != 0)
     185        if (ipc_connect_to_me(PHONE_NS, SERVICE_CLIPBOARD, 0, 0, NULL, NULL))
    187186                return -1;
    188187       
  • uspace/srv/devman/main.c

    ra0ce870 rbf75e3cb  
    586586
    587587        /* Register device manager at naming service. */
    588         sysarg_t phonead;
    589         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
     588        if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, NULL, NULL) != 0)
    590589                return -1;
    591590
  • uspace/srv/devmap/devmap.c

    ra0ce870 rbf75e3cb  
    11501150       
    11511151        /* Register device mapper at naming service */
    1152         sysarg_t phonead;
    1153         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
     1152        if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, NULL, NULL) != 0)
    11541153                return -1;
    11551154       
  • uspace/srv/hid/adb_mouse/adb_dev.c

    ra0ce870 rbf75e3cb  
    6868
    6969        /* NB: The callback connection is slotted for removal */
     70        sysarg_t taskhash;
    7071        sysarg_t phonehash;
    71         if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
     72        if (ipc_connect_to_me(dev_phone, 0, 0, 0, &taskhash, &phonehash) != 0) {
    7273                printf(NAME ": Failed to create callback from device\n");
    7374                return false;
    7475        }
    7576
    76         async_new_connection(phonehash, 0, NULL, adb_dev_events);
     77        async_new_connection(taskhash, phonehash, 0, NULL, adb_dev_events);
    7778
    7879        return 0;
  • uspace/srv/hid/char_mouse/chardev.c

    ra0ce870 rbf75e3cb  
    7070
    7171        /* NB: The callback connection is slotted for removal */
     72        sysarg_t taskhash;
    7273        sysarg_t phonehash;
    73         if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
     74        if (ipc_connect_to_me(dev_phone, 0, 0, 0, &taskhash, &phonehash) != 0) {
    7475                printf(NAME ": Failed to create callback from device\n");
    7576                return false;
    7677        }
    7778
    78         async_new_connection(phonehash, 0, NULL, chardev_events);
     79        async_new_connection(taskhash, phonehash, 0, NULL, chardev_events);
    7980
    8081        return 0;
  • uspace/srv/hid/console/console.c

    ra0ce870 rbf75e3cb  
    726726       
    727727        /* NB: The callback connection is slotted for removal */
     728        sysarg_t taskhash;
    728729        sysarg_t phonehash;
    729         if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
     730        if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &taskhash,
     731            &phonehash) != 0) {
    730732                printf(NAME ": Failed to create callback from input device\n");
    731733                return false;
    732734        }
    733735       
    734         async_new_connection(phonehash, 0, NULL, keyboard_events);
     736        async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
    735737       
    736738        /* Connect to mouse device */
     
    749751        }
    750752       
    751         if (ipc_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
     753        if (ipc_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, &taskhash,
     754            &phonehash) != 0) {
    752755                printf(NAME ": Failed to create callback from mouse device\n");
    753756                mouse_phone = -1;
     
    755758        }
    756759       
    757         async_new_connection(phonehash, 0, NULL, mouse_events);
     760        async_new_connection(taskhash, phonehash, 0, NULL, mouse_events);
    758761skip_mouse:
    759762       
  • uspace/srv/hid/fb/main.c

    ra0ce870 rbf75e3cb  
    114114                return -1;
    115115       
    116         sysarg_t phonead;
    117         if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, &phonead) != 0)
     116        if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, NULL, NULL) != 0)
    118117                return -1;
    119118       
  • uspace/srv/hid/kbd/port/adb.c

    ra0ce870 rbf75e3cb  
    7171
    7272        /* NB: The callback connection is slotted for removal */
     73        sysarg_t taskhash;
    7374        sysarg_t phonehash;
    74         if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
     75        if (ipc_connect_to_me(dev_phone, 0, 0, 0, &taskhash, &phonehash) != 0) {
    7576                printf(NAME ": Failed to create callback from device\n");
    7677                return false;
    7778        }
    7879
    79         async_new_connection(phonehash, 0, NULL, kbd_port_events);
     80        async_new_connection(taskhash, phonehash, 0, NULL, kbd_port_events);
    8081
    8182        return 0;
  • uspace/srv/hid/kbd/port/chardev.c

    ra0ce870 rbf75e3cb  
    9191
    9292        /* NB: The callback connection is slotted for removal */
     93        sysarg_t taskhash;
    9394        sysarg_t phonehash;
    94         if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
     95        if (ipc_connect_to_me(dev_phone, 0, 0, 0, &taskhash, &phonehash) != 0) {
    9596                printf(NAME ": Failed to create callback from device\n");
    9697                return -1;
    9798        }
    9899
    99         async_new_connection(phonehash, 0, NULL, kbd_port_events);
     100        async_new_connection(taskhash, phonehash, 0, NULL, kbd_port_events);
    100101
    101102        return 0;
  • uspace/srv/hw/irc/apic/apic.c

    ra0ce870 rbf75e3cb  
    108108       
    109109        async_set_client_connection(apic_connection);
    110         sysarg_t phonead;
    111         ipc_connect_to_me(PHONE_NS, SERVICE_APIC, 0, 0, &phonead);
     110        ipc_connect_to_me(PHONE_NS, SERVICE_APIC, 0, 0, NULL, NULL);
    112111       
    113112        return true;
  • uspace/srv/hw/irc/fhc/fhc.c

    ra0ce870 rbf75e3cb  
    137137       
    138138        async_set_client_connection(fhc_connection);
    139         sysarg_t phonead;
    140         ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead);
     139        ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, NULL, NULL);
    141140       
    142141        return true;
  • uspace/srv/hw/irc/i8259/i8259.c

    ra0ce870 rbf75e3cb  
    150150       
    151151        async_set_client_connection(i8259_connection);
    152         sysarg_t phonead;
    153         ipc_connect_to_me(PHONE_NS, SERVICE_I8259, 0, 0, &phonead);
     152        ipc_connect_to_me(PHONE_NS, SERVICE_I8259, 0, 0, NULL, NULL);
    154153       
    155154        return true;
  • uspace/srv/hw/irc/obio/obio.c

    ra0ce870 rbf75e3cb  
    138138       
    139139        async_set_client_connection(obio_connection);
    140         sysarg_t phonead;
    141         ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
     140        ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, NULL, NULL);
    142141       
    143142        return true;
  • uspace/srv/hw/netif/ne2000/ne2000.c

    ra0ce870 rbf75e3cb  
    397397        async_set_interrupt_received(irq_handler);
    398398       
    399         sysarg_t phonehash;
    400         return ipc_connect_to_me(PHONE_NS, SERVICE_NE2000, 0, 0, &phonehash);
     399        return ipc_connect_to_me(PHONE_NS, SERVICE_NE2000, 0, 0, NULL, NULL);
    401400}
    402401
  • uspace/srv/loader/main.c

    ra0ce870 rbf75e3cb  
    423423int main(int argc, char *argv[])
    424424{
    425         sysarg_t phonead;
    426425        task_id_t id;
    427426        int rc;
     
    439438       
    440439        /* Register at naming service. */
    441         if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
     440        if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, NULL, NULL) != 0)
    442441                return -2;
    443442
  • uspace/srv/net/net/net.c

    ra0ce870 rbf75e3cb  
    326326static int net_module_start(async_client_conn_t client_connection)
    327327{
    328         sysarg_t phonehash;
    329328        int rc;
    330329       
     
    338337                goto out;
    339338       
    340         rc = ipc_connect_to_me(PHONE_NS, SERVICE_NETWORKING, 0, 0, &phonehash);
     339        rc = ipc_connect_to_me(PHONE_NS, SERVICE_NETWORKING, 0, 0, NULL, NULL);
    341340        if (rc != EOK)
    342341                goto out;
  • uspace/srv/net/netif/lo/lo.c

    ra0ce870 rbf75e3cb  
    167167int netif_initialize(void)
    168168{
    169         sysarg_t phonehash;
    170         return ipc_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, &phonehash);
     169        return ipc_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, NULL, NULL);
    171170}
    172171
  • uspace/srv/vfs/vfs.c

    ra0ce870 rbf75e3cb  
    5959        ipc_answer_0(iid, EOK);
    6060       
    61         /*
    62          * Here we enter the main connection fibril loop.
    63          * The logic behind this loop and the protocol is that we'd like to keep
    64          * each connection open until the client hangs up. When the client hangs
    65          * up, we will free its VFS state. The act of hanging up the connection
    66          * by the client is equivalent to client termination because we cannot
    67          * distinguish one from the other. On the other hand, the client can
    68          * hang up arbitrarily if it has no open files and reestablish the
    69          * connection later.
    70          */
    7161        while (keep_on_going) {
    7262                ipc_call_t call;
     
    133123                }
    134124        }
    135        
    136         vfs_files_done();
     125
     126        /*
     127         * Open files for this client will be cleaned up when its last
     128         * connection fibril terminates.
     129         */
    137130}
    138131
     
    166159       
    167160        /*
     161         * Set client data constructor and destructor.
     162         */
     163        async_set_client_data_constructor(vfs_client_data_create);
     164        async_set_client_data_destructor(vfs_client_data_destroy);
     165
     166        /*
    168167         * Set a connection handling function/fibril.
    169168         */
     
    173172         * Register at the naming service.
    174173         */
    175         sysarg_t phonead;
    176         ipc_connect_to_me(PHONE_NS, SERVICE_VFS, 0, 0, &phonead);
     174        ipc_connect_to_me(PHONE_NS, SERVICE_VFS, 0, 0, NULL, NULL);
    177175       
    178176        /*
  • uspace/srv/vfs/vfs.h

    ra0ce870 rbf75e3cb  
    188188#define MAX_OPEN_FILES  128
    189189
    190 extern bool vfs_files_init(void);
    191 extern void vfs_files_done(void);
     190extern void *vfs_client_data_create(void);
     191extern void vfs_client_data_destroy(void *);
     192
    192193extern vfs_file_t *vfs_file_get(int);
    193 extern int vfs_fd_assign(vfs_file_t *file, int fd);
     194extern void vfs_file_put(vfs_file_t *);
     195extern int vfs_fd_assign(vfs_file_t *, int);
    194196extern int vfs_fd_alloc(bool desc);
    195197extern int vfs_fd_free(int);
    196 
    197 extern void vfs_file_addref(vfs_file_t *);
    198 extern void vfs_file_delref(vfs_file_t *);
    199198
    200199extern void vfs_node_addref(vfs_node_t *);
  • uspace/srv/vfs/vfs_file.c

    ra0ce870 rbf75e3cb  
    4545#include "vfs.h"
    4646
    47 /**
    48  * This is a per-connection table of open files.
    49  * Our assumption is that each client opens only one connection and therefore
    50  * there is one table of open files per task. However, this may not be the case
    51  * and the client can open more connections to VFS. In that case, there will be
    52  * several tables and several file handle name spaces per task. Besides of this,
    53  * the functionality will stay unchanged. So unless the client knows what it is
    54  * doing, it should open one connection to VFS only.
    55  *
    56  * Allocation of the open files table is deferred until the client makes the
    57  * first VFS_OPEN operation.
    58  *
    59  * This resource being per-connection and, in the first place, per-fibril, we
    60  * don't need to protect it by a mutex.
    61  */
    62 fibril_local vfs_file_t **files = NULL;
     47#define VFS_DATA        ((vfs_client_data_t *) async_client_data_get())
     48#define FILES           (VFS_DATA->files)
     49
     50typedef struct {
     51        fibril_mutex_t lock;
     52        vfs_file_t **files;
     53} vfs_client_data_t;
    6354
    6455/** Initialize the table of open files. */
    65 bool vfs_files_init(void)
    66 {
    67         if (!files) {
    68                 files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
    69                 if (!files)
     56static bool vfs_files_init(void)
     57{
     58        fibril_mutex_lock(&VFS_DATA->lock);
     59        if (!FILES) {
     60                FILES = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
     61                if (!FILES) {
     62                        fibril_mutex_unlock(&VFS_DATA->lock);
    7063                        return false;
    71                 memset(files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
    72         }
     64                }
     65                memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
     66        }
     67        fibril_mutex_unlock(&VFS_DATA->lock);
    7368        return true;
    7469}
    7570
    7671/** Cleanup the table of open files. */
    77 void vfs_files_done(void)
     72static void vfs_files_done(void)
    7873{
    7974        int i;
    8075
    81         if (!files)
     76        if (!FILES)
    8277                return;
    8378
    8479        for (i = 0; i < MAX_OPEN_FILES; i++) {
    85                 if (files[i]) {
    86                         (void) vfs_close_internal(files[i]);
     80                if (FILES[i]) {
     81                        (void) vfs_close_internal(FILES[i]);
    8782                        (void) vfs_fd_free(i);
    8883                }
    8984        }
    9085       
    91         free(files);
    92 }
     86        free(FILES);
     87}
     88
     89void *vfs_client_data_create(void)
     90{
     91        vfs_client_data_t *vfs_data;
     92
     93        vfs_data = malloc(sizeof(vfs_client_data_t));
     94        if (vfs_data) {
     95                fibril_mutex_initialize(&vfs_data->lock);
     96                vfs_data->files = NULL;
     97        }
     98       
     99        return vfs_data;
     100}
     101
     102void vfs_client_data_destroy(void *data)
     103{
     104        vfs_client_data_t *vfs_data = (vfs_client_data_t *) data;
     105
     106        vfs_files_done();
     107        free(vfs_data);
     108}
     109
     110/** Increment reference count of VFS file structure.
     111 *
     112 * @param file          File structure that will have reference count
     113 *                      incremented.
     114 */
     115static void vfs_file_addref(vfs_file_t *file)
     116{
     117        assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     118
     119        file->refcnt++;
     120}
     121
     122/** Decrement reference count of VFS file structure.
     123 *
     124 * @param file          File structure that will have reference count
     125 *                      decremented.
     126 */
     127static void vfs_file_delref(vfs_file_t *file)
     128{
     129        assert(fibril_mutex_is_locked(&VFS_DATA->lock));
     130
     131        if (file->refcnt-- == 1) {
     132                /*
     133                 * Lost the last reference to a file, need to drop our reference
     134                 * to the underlying VFS node.
     135                 */
     136                vfs_node_delref(file->node);
     137                free(file);
     138        }
     139}
     140
    93141
    94142/** Allocate a file descriptor.
     
    111159                i = 0;
    112160       
     161        fibril_mutex_lock(&VFS_DATA->lock);
    113162        while (true) {
    114                 if (!files[i]) {
    115                         files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
    116                         if (!files[i])
     163                if (!FILES[i]) {
     164                        FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
     165                        if (!FILES[i]) {
     166                                fibril_mutex_unlock(&VFS_DATA->lock);
    117167                                return ENOMEM;
     168                        }
    118169                       
    119                         memset(files[i], 0, sizeof(vfs_file_t));
    120                         fibril_mutex_initialize(&files[i]->lock);
    121                         vfs_file_addref(files[i]);
     170                        memset(FILES[i], 0, sizeof(vfs_file_t));
     171                        fibril_mutex_initialize(&FILES[i]->lock);
     172                        vfs_file_addref(FILES[i]);
     173                        fibril_mutex_unlock(&VFS_DATA->lock);
    122174                        return (int) i;
    123175                }
     
    135187                }
    136188        }
     189        fibril_mutex_unlock(&VFS_DATA->lock);
    137190       
    138191        return EMFILE;
     
    150203        if (!vfs_files_init())
    151204                return ENOMEM;
    152        
    153         if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] == NULL))
     205
     206        fibril_mutex_lock(&VFS_DATA->lock);     
     207        if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) {
     208                fibril_mutex_unlock(&VFS_DATA->lock);
    154209                return EBADF;
    155        
    156         vfs_file_delref(files[fd]);
    157         files[fd] = NULL;
     210        }
     211       
     212        vfs_file_delref(FILES[fd]);
     213        FILES[fd] = NULL;
     214        fibril_mutex_unlock(&VFS_DATA->lock);
    158215       
    159216        return EOK;
     
    173230        if (!vfs_files_init())
    174231                return ENOMEM;
    175        
    176         if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] != NULL))
     232
     233        fibril_mutex_lock(&VFS_DATA->lock);     
     234        if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] != NULL)) {
     235                fibril_mutex_unlock(&VFS_DATA->lock);
    177236                return EINVAL;
    178        
    179         files[fd] = file;
    180         vfs_file_addref(files[fd]);
     237        }
     238       
     239        FILES[fd] = file;
     240        vfs_file_addref(FILES[fd]);
     241        fibril_mutex_unlock(&VFS_DATA->lock);
    181242       
    182243        return EOK;
    183244}
    184245
    185 /** Increment reference count of VFS file structure.
    186  *
    187  * @param file          File structure that will have reference count
    188  *                      incremented.
    189  */
    190 void vfs_file_addref(vfs_file_t *file)
    191 {
    192         /*
    193          * File structures are per-connection, so no-one, except the current
    194          * fibril, should have a reference to them. This is the reason we don't
    195          * do any synchronization here.
    196          */
    197         file->refcnt++;
    198 }
    199 
    200 /** Decrement reference count of VFS file structure.
    201  *
    202  * @param file          File structure that will have reference count
    203  *                      decremented.
    204  */
    205 void vfs_file_delref(vfs_file_t *file)
    206 {
    207         if (file->refcnt-- == 1) {
    208                 /*
    209                  * Lost the last reference to a file, need to drop our reference
    210                  * to the underlying VFS node.
    211                  */
    212                 vfs_node_delref(file->node);
    213                 free(file);
    214         }
    215 }
    216 
    217246/** Find VFS file structure for a given file descriptor.
    218247 *
     
    226255                return NULL;
    227256       
    228         if ((fd >= 0) && (fd < MAX_OPEN_FILES))
    229                 return files[fd];
     257        fibril_mutex_lock(&VFS_DATA->lock);
     258        if ((fd >= 0) && (fd < MAX_OPEN_FILES)) {
     259                vfs_file_t *file = FILES[fd];
     260                vfs_file_addref(file);
     261                fibril_mutex_unlock(&VFS_DATA->lock);
     262                return file;
     263        }
     264        fibril_mutex_unlock(&VFS_DATA->lock);
    230265       
    231266        return NULL;
     267}
     268
     269/** Stop using a file structure.
     270 *
     271 * @param file          VFS file structure.
     272 */
     273void vfs_file_put(vfs_file_t *file)
     274{
     275        fibril_mutex_lock(&VFS_DATA->lock);
     276        vfs_file_delref(file);
     277        fibril_mutex_unlock(&VFS_DATA->lock);
    232278}
    233279
  • uspace/srv/vfs/vfs_ops.c

    ra0ce870 rbf75e3cb  
    491491void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    492492{
    493         if (!vfs_files_init()) {
    494                 ipc_answer_0(rid, ENOMEM);
    495                 return;
    496         }
    497        
    498493        /*
    499494         * The POSIX interface is open(path, oflag, mode).
     
    609604        vfs_node_addref(node);
    610605        vfs_node_put(node);
     606        vfs_file_put(file);
    611607       
    612608        /* Success! Return the new file descriptor to the client. */
     
    617613{
    618614        // FIXME: check for sanity of the supplied fs, dev and index
    619        
    620         if (!vfs_files_init()) {
    621                 ipc_answer_0(rid, ENOMEM);
    622                 return;
    623         }
    624615       
    625616        /*
     
    686677        vfs_node_addref(node);
    687678        vfs_node_put(node);
     679        vfs_file_put(file);
    688680       
    689681        /* Success! Return the new file descriptor to the client. */
     
    721713        vfs_release_phone(file->node->fs_handle, fs_phone);
    722714        fibril_mutex_unlock(&file->lock);
    723        
     715
     716        vfs_file_put(file);
    724717        ipc_answer_0(rid, rc);
    725718}
     
    775768                ipc_answer_0(rid, ret);
    776769       
     770        vfs_file_put(file);
    777771        ret = vfs_fd_free(fd);
    778772        ipc_answer_0(rid, ret);
     
    875869                file->pos += bytes;
    876870        fibril_mutex_unlock(&file->lock);
    877        
     871        vfs_file_put(file);     
     872
    878873        /*
    879874         * FS server's reply is the final result of the whole operation we
     
    915910                        file->pos = (aoff64_t) off;
    916911                        fibril_mutex_unlock(&file->lock);
     912                        vfs_file_put(file);
    917913                        ipc_answer_1(rid, EOK, off);
    918914                        return;
     
    922918                if ((off >= 0) && (file->pos + off < file->pos)) {
    923919                        fibril_mutex_unlock(&file->lock);
     920                        vfs_file_put(file);
    924921                        ipc_answer_0(rid, EOVERFLOW);
    925922                        return;
     
    928925                if ((off < 0) && (file->pos < (aoff64_t) -off)) {
    929926                        fibril_mutex_unlock(&file->lock);
     927                        vfs_file_put(file);
    930928                        ipc_answer_0(rid, EOVERFLOW);
    931929                        return;
     
    936934               
    937935                fibril_mutex_unlock(&file->lock);
     936                vfs_file_put(file);
    938937                ipc_answer_2(rid, EOK, LOWER32(newoff),
    939938                    UPPER32(newoff));
     
    946945                        fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    947946                        fibril_mutex_unlock(&file->lock);
     947                        vfs_file_put(file);
    948948                        ipc_answer_0(rid, EOVERFLOW);
    949949                        return;
     
    953953                        fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    954954                        fibril_mutex_unlock(&file->lock);
     955                        vfs_file_put(file);
    955956                        ipc_answer_0(rid, EOVERFLOW);
    956957                        return;
     
    962963                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    963964                fibril_mutex_unlock(&file->lock);
     965                vfs_file_put(file);
    964966                ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    965967                return;
     
    967969       
    968970        fibril_mutex_unlock(&file->lock);
     971        vfs_file_put(file);
    969972        ipc_answer_0(rid, EINVAL);
    970973}
     
    10051008
    10061009        fibril_mutex_unlock(&file->lock);
     1010        vfs_file_put(file);
    10071011        ipc_answer_0(rid, (sysarg_t)rc);
    10081012}
     
    10211025        ipc_callid_t callid;
    10221026        if (!async_data_read_receive(&callid, NULL)) {
     1027                vfs_file_put(file);
    10231028                ipc_answer_0(callid, EINVAL);
    10241029                ipc_answer_0(rid, EINVAL);
     
    10381043
    10391044        fibril_mutex_unlock(&file->lock);
     1045        vfs_file_put(file);
    10401046        ipc_answer_0(rid, rc);
    10411047}
     
    13391345        int newfd = IPC_GET_ARG2(*request);
    13401346       
     1347        /* If the file descriptors are the same, do nothing. */
     1348        if (oldfd == newfd) {
     1349                ipc_answer_1(rid, EOK, newfd);
     1350                return;
     1351        }
     1352       
    13411353        /* Lookup the file structure corresponding to oldfd. */
    13421354        vfs_file_t *oldfile = vfs_file_get(oldfd);
    13431355        if (!oldfile) {
    13441356                ipc_answer_0(rid, EBADF);
    1345                 return;
    1346         }
    1347        
    1348         /* If the file descriptors are the same, do nothing. */
    1349         if (oldfd == newfd) {
    1350                 ipc_answer_1(rid, EOK, newfd);
    13511357                return;
    13521358        }
     
    13651371                if (ret != EOK) {
    13661372                        fibril_mutex_unlock(&oldfile->lock);
     1373                        vfs_file_put(oldfile);
     1374                        vfs_file_put(newfile);
    13671375                        ipc_answer_0(rid, ret);
    13681376                        return;
     
    13721380                if (ret != EOK) {
    13731381                        fibril_mutex_unlock(&oldfile->lock);
     1382                        vfs_file_put(oldfile);
     1383                        vfs_file_put(newfile);
    13741384                        ipc_answer_0(rid, ret);
    13751385                        return;
    13761386                }
     1387                vfs_file_put(newfile);
    13771388        }
    13781389       
     
    13801391        int ret = vfs_fd_assign(oldfile, newfd);
    13811392        fibril_mutex_unlock(&oldfile->lock);
     1393        vfs_file_put(oldfile);
    13821394       
    13831395        if (ret != EOK)
Note: See TracChangeset for help on using the changeset viewer.