Changeset a33f0a6 in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2011-08-03T17:34:57Z (14 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1940326
Parents:
52a79081 (diff), 3fab770 (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 mainline

Location:
uspace/lib/c/generic
Files:
11 added
1 deleted
34 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/adt/hash_table.c

    r52a79081 ra33f0a6  
    5454 *
    5555 */
    56 int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
     56bool hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
    5757    hash_table_operations_t *op)
    5858{
     
    6161        assert(max_keys > 0);
    6262       
    63         h->entry = malloc(m * sizeof(link_t));
     63        h->entry = malloc(m * sizeof(list_t));
    6464        if (!h->entry)
    6565                return false;
    6666       
    67         memset((void *) h->entry, 0,  m * sizeof(link_t));
     67        memset((void *) h->entry, 0,  m * sizeof(list_t));
    6868       
    6969        hash_count_t i;
     
    123123        assert(chain < h->entries);
    124124       
    125         link_t *cur;
    126         for (cur = h->entry[chain].next; cur != &h->entry[chain];
    127             cur = cur->next) {
     125        list_foreach(h->entry[chain], cur) {
    128126                if (h->op->compare(key, h->max_keys, cur)) {
    129127                        /*
     
    153151        assert(keys <= h->max_keys);
    154152       
    155         link_t *cur;
    156        
    157153        if (keys == h->max_keys) {
     154                link_t *cur;
     155               
    158156                /*
    159157                 * All keys are known, hash_table_find() can be used to find the
     
    176174        hash_index_t chain;
    177175        for (chain = 0; chain < h->entries; chain++) {
    178                 for (cur = h->entry[chain].next; cur != &h->entry[chain];
     176                link_t *cur;
     177               
     178                for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head;
    179179                    cur = cur->next) {
    180180                        if (h->op->compare(key, keys, cur)) {
     
    203203{
    204204        hash_index_t bucket;
    205         link_t *cur;
    206205       
    207206        for (bucket = 0; bucket < h->entries; bucket++) {
    208                 for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
    209                     cur = cur->next) {
     207                list_foreach(h->entry[bucket], cur) {
    210208                        f(cur, arg);
    211209                }
  • uspace/lib/c/generic/adt/list.c

    r52a79081 ra33f0a6  
    3030 * @{
    3131 */
    32 /** @file
     32
     33/**
     34 * @file
     35 * @brief       Functions completing doubly linked circular list implementaion.
     36 *
     37 * This file contains some of the functions implementing doubly linked circular lists.
     38 * However, this ADT is mostly implemented in @ref list.h.
    3339 */
    3440
    3541#include <adt/list.h>
    36 
     42#include <bool.h>
    3743
    3844/** Check for membership
    3945 *
    40  * Check whether link is contained in the list head.
    41  * The membership is defined as pointer equivalence.
     46 * Check whether link is contained in a list.
     47 * Membership is defined as pointer equivalence.
    4248 *
    43  * @param link Item to look for.
    44  * @param head List to look in.
     49 * @param link  Item to look for.
     50 * @param list  List to look in.
    4551 *
    4652 * @return true if link is contained in head, false otherwise.
    4753 *
    4854 */
    49 int list_member(const link_t *link, const link_t *head)
     55int list_member(const link_t *link, const list_t *list)
    5056{
    51         int found = 0;
    52         link_t *hlp = head->next;
     57        bool found = false;
     58        link_t *hlp = list->head.next;
    5359       
    54         while (hlp != head) {
     60        while (hlp != &list->head) {
    5561                if (hlp == link) {
    56                         found = 1;
     62                        found = true;
    5763                        break;
    5864                }
     
    6369}
    6470
    65 
    6671/** Concatenate two lists
    6772 *
    68  * Concatenate lists head1 and head2, producing a single
    69  * list head1 containing items from both (in head1, head2
    70  * order) and empty list head2.
     73 * Concatenate lists @a list1 and @a list2, producing a single
     74 * list @a list1 containing items from both (in @a list1, @a list2
     75 * order) and empty list @a list2.
    7176 *
    72  * @param head1 First list and concatenated output
    73  * @param head2 Second list and empty output.
     77 * @param list1         First list and concatenated output
     78 * @param list2         Second list and empty output.
    7479 *
    7580 */
    76 void list_concat(link_t *head1, link_t *head2)
     81void list_concat(list_t *list1, list_t *list2)
    7782{
    78         if (list_empty(head2))
     83        if (list_empty(list2))
    7984                return;
    80        
    81         head2->next->prev = head1->prev;
    82         head2->prev->next = head1;
    83         head1->prev->next = head2->next;
    84         head1->prev = head2->prev;
    85         list_initialize(head2);
     85
     86        list2->head.next->prev = list1->head.prev;
     87        list2->head.prev->next = &list1->head;
     88        list1->head.prev->next = list2->head.next;
     89        list1->head.prev = list2->head.prev;
     90        list_initialize(list2);
    8691}
    87 
    8892
    8993/** Count list items
     
    9195 * Return the number of items in the list.
    9296 *
    93  * @param link List to count.
    94  *
    95  * @return Number of items in the list.
    96  *
     97 * @param list          List to count.
     98 * @return              Number of items in the list.
    9799 */
    98 unsigned int list_count(const link_t *link)
     100unsigned int list_count(const list_t *list)
    99101{
    100102        unsigned int count = 0;
    101         link_t *hlp = link->next;
    102103       
    103         while (hlp != link) {
     104        list_foreach(*list, link) {
    104105                count++;
    105                 hlp = hlp->next;
    106106        }
    107107       
  • uspace/lib/c/generic/adt/measured_strings.c

    r52a79081 ra33f0a6  
    297297 * size has to be negotiated in advance.
    298298 *
    299  * @param[in] phone     The other module phone.
     299 * @param[in] exch      Exchange.
    300300 * @param[out] strings  The returned measured strings array.
    301301 * @param[out] data     The measured strings data. This memory block stores the
     
    304304 * @return              EOK on success.
    305305 * @return              EINVAL if the strings or data parameter is NULL.
    306  * @return              EINVAL if the phone or count parameter is not positive.
     306 * @return              EINVAL if the exch or count parameter is invalid.
    307307 * @return              EINVAL if the sent array differs in size.
    308308 * @return              ENOMEM if there is not enough memory left.
     
    310310 *                      async_data_read_start() function.
    311311 */
    312 int
    313 measured_strings_return(int phone, measured_string_t **strings, uint8_t **data,
    314     size_t count)
     312int measured_strings_return(async_exch_t *exch, measured_string_t **strings,
     313    uint8_t **data, size_t count)
    315314{
    316315        size_t *lengths;
     
    319318        int rc;
    320319
    321         if ((phone < 0) || (!strings) || (!data) || (count <= 0))
     320        if ((exch == NULL) || (!strings) || (!data) || (count <= 0))
    322321                return EINVAL;
    323322
     
    326325                return ENOMEM;
    327326
    328         rc = async_data_read_start(phone, lengths,
     327        rc = async_data_read_start(exch, lengths,
    329328            sizeof(size_t) * (count + 1));
    330329        if (rc != EOK) {
     
    351350                (*strings)[index].length = lengths[index];
    352351                if (lengths[index] > 0) {
    353                         rc = async_data_read_start(phone, next, lengths[index]);
     352                        rc = async_data_read_start(exch, next, lengths[index]);
    354353                        if (rc != EOK) {
    355354                                free(lengths);
     
    375374 * size has to be negotiated in advance.
    376375 *
    377  * @param[in] phone     The other module phone.
     376 * @param[in] exch      Exchange.
    378377 * @param[in] strings   The measured strings array to be transferred.
    379378 * @param[in] count     The measured strings array size.
    380379 * @return              EOK on success.
    381380 * @return              EINVAL if the strings parameter is NULL.
    382  * @return              EINVAL if the phone or count parameter is not positive.
     381 * @return              EINVAL if the exch or count parameter is invalid.
    383382 * @return              Other error codes as defined for the
    384383 *                      async_data_write_start() function.
    385384 */
    386 int
    387 measured_strings_send(int phone, const measured_string_t *strings,
     385int measured_strings_send(async_exch_t *exch, const measured_string_t *strings,
    388386    size_t count)
    389387{
     
    392390        int rc;
    393391
    394         if ((phone < 0) || (!strings) || (count <= 0))
     392        if ((exch == NULL) || (!strings) || (count <= 0))
    395393                return EINVAL;
    396394
     
    399397                return ENOMEM;
    400398
    401         rc = async_data_write_start(phone, lengths,
     399        rc = async_data_write_start(exch, lengths,
    402400            sizeof(size_t) * (count + 1));
    403401        if (rc != EOK) {
     
    410408        for (index = 0; index < count; index++) {
    411409                if (strings[index].length > 0) {
    412                         rc = async_data_write_start(phone, strings[index].value,
     410                        rc = async_data_write_start(exch, strings[index].value,
    413411                            strings[index].length);
    414412                        if (rc != EOK)
     
    422420/** @}
    423421 */
    424 
  • uspace/lib/c/generic/as.c

    r52a79081 ra33f0a6  
    3535#include <as.h>
    3636#include <libc.h>
     37#include <errno.h>
    3738#include <unistd.h>
    3839#include <align.h>
     
    5152 *
    5253 */
    53 void *as_area_create(void *address, size_t size, int flags)
     54void *as_area_create(void *address, size_t size, unsigned int flags)
    5455{
    5556        return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address,
     
    6768 *
    6869 */
    69 int as_area_resize(void *address, size_t size, int flags)
     70int as_area_resize(void *address, size_t size, unsigned int flags)
    7071{
    7172        return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address,
     
    9596 *
    9697 */
    97 int as_area_change_flags(void *address, int flags)
     98int as_area_change_flags(void *address, unsigned int flags)
    9899{
    99100        return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address,
     
    114115}
    115116
     117/** Find mapping to physical address.
     118 *
     119 * @param address Virtual address in question (virtual).
     120 * @param[out] frame Frame address (physical).
     121 * @return Error code.
     122 * @retval EOK No error, @p frame holds the translation.
     123 * @retval ENOENT Mapping not found.
     124 */
     125int as_get_physical_mapping(void *address, uintptr_t *frame)
     126{
     127        uintptr_t tmp_frame;
     128        uintptr_t virt = (uintptr_t) address;
     129       
     130        int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING,
     131            (sysarg_t) virt, (sysarg_t) &tmp_frame);
     132        if (rc != EOK) {
     133                return rc;
     134        }
     135       
     136        if (frame != NULL) {
     137                *frame = tmp_frame;
     138        }
     139       
     140        return EOK;
     141}
     142
    116143/** @}
    117144 */
  • uspace/lib/c/generic/assert.c

    r52a79081 ra33f0a6  
    3333#include <assert.h>
    3434#include <stdio.h>
     35#include <io/klog.h>
    3536#include <stdlib.h>
     37#include <atomic.h>
    3638#include <stacktrace.h>
     39#include <stdint.h>
     40
     41static atomic_t failed_asserts = {0};
    3742
    3843void assert_abort(const char *cond, const char *file, unsigned int line)
    3944{
     45        /*
     46         * Send the message safely to klog. Nested asserts should not occur.
     47         */
     48        klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
     49            cond, file, line);
     50       
     51        /*
     52         * Check if this is a nested or parallel assert.
     53         */
     54        if (atomic_postinc(&failed_asserts))
     55                abort();
     56       
     57        /*
     58         * Attempt to print the message to standard output and display
     59         * the stack trace. These operations can theoretically trigger nested
     60         * assertions.
     61         */
    4062        printf("Assertion failed (%s) in file \"%s\", line %u.\n",
    4163            cond, file, line);
    4264        stacktrace_print();
     65       
    4366        abort();
    4467}
  • uspace/lib/c/generic/async.c

    r52a79081 ra33f0a6  
    4040 * programming.
    4141 *
    42  * You should be able to write very simple multithreaded programs, the async
    43  * framework will automatically take care of most synchronization problems.
     42 * You should be able to write very simple multithreaded programs. The async
     43 * framework will automatically take care of most of the synchronization
     44 * problems.
    4445 *
    4546 * Example of use (pseudo C):
     
    5354 *   int fibril1(void *arg)
    5455 *   {
    55  *     conn = async_connect_me_to();
    56  *     c1 = async_send(conn);
    57  *     c2 = async_send(conn);
     56 *     conn = async_connect_me_to(...);
     57 *
     58 *     exch = async_exchange_begin(conn);
     59 *     c1 = async_send(exch);
     60 *     async_exchange_end(exch);
     61 *
     62 *     exch = async_exchange_begin(conn);
     63 *     c2 = async_send(exch);
     64 *     async_exchange_end(exch);
     65 *
    5866 *     async_wait_for(c1);
    5967 *     async_wait_for(c2);
     
    94102#include <futex.h>
    95103#include <fibril.h>
    96 #include <stdio.h>
    97104#include <adt/hash_table.h>
    98105#include <adt/list.h>
     
    102109#include <arch/barrier.h>
    103110#include <bool.h>
     111#include <malloc.h>
     112#include <mem.h>
    104113#include <stdlib.h>
    105 #include <malloc.h>
    106114#include "private/async.h"
    107115
     116#define CLIENT_HASH_TABLE_BUCKETS  32
     117#define CONN_HASH_TABLE_BUCKETS    32
     118
     119/** Async framework global futex */
    108120atomic_t async_futex = FUTEX_INITIALIZER;
    109121
     
    111123atomic_t threads_in_ipc_wait = { 0 };
    112124
    113 typedef struct {
    114         awaiter_t wdata;
    115        
    116         /** If reply was received. */
    117         bool done;
    118        
    119         /** Pointer to where the answer data is stored. */
    120         ipc_call_t *dataptr;
    121        
    122         sysarg_t retval;
    123 } amsg_t;
    124 
    125 /**
    126  * Structures of this type are used to group information about
    127  * a call and about a message queue link.
    128  */
     125/** Naming service session */
     126async_sess_t *session_ns;
     127
     128/** Call data */
    129129typedef struct {
    130130        link_t link;
     131       
    131132        ipc_callid_t callid;
    132133        ipc_call_t call;
    133134} msg_t;
    134135
     136/* Client connection data */
    135137typedef struct {
     138        link_t link;
     139       
    136140        sysarg_t in_task_hash;
    137         link_t link;
    138         int refcnt;
     141        atomic_t refcnt;
    139142        void *data;
    140143} client_t;
    141144
     145/* Server connection data */
    142146typedef struct {
    143147        awaiter_t wdata;
     
    148152        /** Incoming client task hash. */
    149153        sysarg_t in_task_hash;
     154       
    150155        /** Incoming phone hash. */
    151156        sysarg_t in_phone_hash;
     
    155160       
    156161        /** Messages that should be delivered to this fibril. */
    157         link_t msg_queue;
     162        list_t msg_queue;
    158163       
    159164        /** Identification of the opening call. */
     
    161166        /** Call data of the opening call. */
    162167        ipc_call_t call;
     168        /** Local argument or NULL if none. */
     169        void *carg;
    163170       
    164171        /** Identification of the closing call. */
     
    166173       
    167174        /** Fibril function that will be used to handle the connection. */
    168         void (*cfibril)(ipc_callid_t, ipc_call_t *);
     175        async_client_conn_t cfibril;
    169176} connection_t;
    170177
    171178/** Identifier of the incoming connection handled by the current fibril. */
    172 static fibril_local connection_t *FIBRIL_connection;
     179static fibril_local connection_t *fibril_connection;
    173180
    174181static void *default_client_data_constructor(void)
     
    196203}
    197204
    198 void *async_client_data_get(void)
    199 {
    200         assert(FIBRIL_connection);
    201         return FIBRIL_connection->client->data;
     205void *async_get_client_data(void)
     206{
     207        assert(fibril_connection);
     208        return fibril_connection->client->data;
    202209}
    203210
     
    208215 * @param callid Hash of the incoming call.
    209216 * @param call   Data of the incoming call.
    210  *
    211  */
    212 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     217 * @param arg    Local argument
     218 *
     219 */
     220static void default_client_connection(ipc_callid_t callid, ipc_call_t *call,
     221    void *arg)
    213222{
    214223        ipc_answer_0(callid, ENOENT);
    215224}
    216 
    217 /**
    218  * Pointer to a fibril function that will be used to handle connections.
    219  */
    220 static async_client_conn_t client_connection = default_client_connection;
    221225
    222226/** Default fibril function that gets called to handle interrupt notifications.
     
    226230 * @param callid Hash of the incoming call.
    227231 * @param call   Data of the incoming call.
     232 * @param arg    Local argument.
    228233 *
    229234 */
     
    232237}
    233238
    234 /**
    235  * Pointer to a fibril function that will be used to handle interrupt
    236  * notifications.
    237  */
    238 static async_client_conn_t interrupt_received = default_interrupt_received;
     239static async_client_conn_t client_connection = default_client_connection;
     240static async_interrupt_handler_t interrupt_received = default_interrupt_received;
     241
     242/** Setter for client_connection function pointer.
     243 *
     244 * @param conn Function that will implement a new connection fibril.
     245 *
     246 */
     247void async_set_client_connection(async_client_conn_t conn)
     248{
     249        client_connection = conn;
     250}
     251
     252/** Setter for interrupt_received function pointer.
     253 *
     254 * @param intr Function that will implement a new interrupt
     255 *             notification fibril.
     256 */
     257void async_set_interrupt_received(async_interrupt_handler_t intr)
     258{
     259        interrupt_received = intr;
     260}
     261
     262/** Mutex protecting inactive_exch_list and avail_phone_cv.
     263 *
     264 */
     265static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex);
     266
     267/** List of all currently inactive exchanges.
     268 *
     269 */
     270static LIST_INITIALIZE(inactive_exch_list);
     271
     272/** Condition variable to wait for a phone to become available.
     273 *
     274 */
     275static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
    239276
    240277static hash_table_t client_hash_table;
     
    242279static LIST_INITIALIZE(timeout_list);
    243280
    244 #define CLIENT_HASH_TABLE_BUCKETS  32
    245 #define CONN_HASH_TABLE_BUCKETS    32
    246 
    247281static hash_index_t client_hash(unsigned long key[])
    248282{
    249283        assert(key);
     284       
    250285        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    251286}
     
    253288static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    254289{
     290        assert(key);
     291        assert(item);
     292       
    255293        client_t *client = hash_table_get_instance(item, client_t, link);
    256294        return (key[0] == client->in_task_hash);
     
    278316{
    279317        assert(key);
     318       
    280319        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    281320}
     
    292331static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    293332{
     333        assert(key);
     334        assert(item);
     335       
    294336        connection_t *conn = hash_table_get_instance(item, connection_t, link);
    295337        return (key[0] == conn->in_phone_hash);
     
    314356void async_insert_timeout(awaiter_t *wd)
    315357{
     358        assert(wd);
     359       
    316360        wd->to_event.occurred = false;
    317361        wd->to_event.inlist = true;
    318362       
    319         link_t *tmp = timeout_list.next;
    320         while (tmp != &timeout_list) {
     363        link_t *tmp = timeout_list.head.next;
     364        while (tmp != &timeout_list.head) {
    321365                awaiter_t *cur
    322366                    = list_get_instance(tmp, awaiter_t, to_event.link);
     
    328372        }
    329373       
    330         list_append(&wd->to_event.link, tmp);
     374        list_insert_before(&wd->to_event.link, tmp);
    331375}
    332376
     
    346390static bool route_call(ipc_callid_t callid, ipc_call_t *call)
    347391{
     392        assert(call);
     393       
    348394        futex_down(&async_futex);
    349395       
     
    400446static int notification_fibril(void *arg)
    401447{
     448        assert(arg);
     449       
    402450        msg_t *msg = (msg_t *) arg;
    403451        interrupt_received(msg->callid, &msg->call);
     
    420468static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
    421469{
     470        assert(call);
     471       
    422472        futex_down(&async_futex);
    423473       
     
    458508ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
    459509{
    460         assert(FIBRIL_connection);
     510        assert(call);
     511        assert(fibril_connection);
    461512       
    462513        /* Why doing this?
    463          * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
     514         * GCC 4.1.0 coughs on fibril_connection-> dereference.
    464515         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    465516         *           I would never expect to find so many errors in
    466517         *           a compiler.
    467518         */
    468         connection_t *conn = FIBRIL_connection;
     519        connection_t *conn = fibril_connection;
    469520       
    470521        futex_down(&async_futex);
     
    518569        }
    519570       
    520         msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link);
     571        msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link);
    521572        list_remove(&msg->link);
    522573       
     
    541592static int connection_fibril(void *arg)
    542593{
     594        assert(arg);
     595       
    543596        /*
    544597         * Setup fibril-local connection pointer.
    545598         */
    546         FIBRIL_connection = (connection_t *) arg;
     599        fibril_connection = (connection_t *) arg;
    547600       
    548601        futex_down(&async_futex);
     
    554607         */
    555608       
    556         unsigned long key = FIBRIL_connection->in_task_hash;
     609        unsigned long key = fibril_connection->in_task_hash;
    557610        link_t *lnk = hash_table_find(&client_hash_table, &key);
    558611       
     
    561614        if (lnk) {
    562615                client = hash_table_get_instance(lnk, client_t, link);
    563                 client->refcnt++;
     616                atomic_inc(&client->refcnt);
    564617        } else {
    565618                client = malloc(sizeof(client_t));
    566619                if (!client) {
    567                         ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
     620                        ipc_answer_0(fibril_connection->callid, ENOMEM);
    568621                        futex_up(&async_futex);
    569622                        return 0;
    570623                }
    571624               
    572                 client->in_task_hash = FIBRIL_connection->in_task_hash;
    573                
    574                 async_serialize_start();
     625                client->in_task_hash = fibril_connection->in_task_hash;
    575626                client->data = async_client_data_create();
    576                 async_serialize_end();
    577                
    578                 client->refcnt = 1;
     627               
     628                atomic_set(&client->refcnt, 1);
    579629                hash_table_insert(&client_hash_table, &key, &client->link);
    580630        }
     
    582632        futex_up(&async_futex);
    583633       
    584         FIBRIL_connection->client = client;
     634        fibril_connection->client = client;
    585635       
    586636        /*
    587637         * Call the connection handler function.
    588638         */
    589         FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    590             &FIBRIL_connection->call);
     639        fibril_connection->cfibril(fibril_connection->callid,
     640            &fibril_connection->call, fibril_connection->carg);
    591641       
    592642        /*
     
    597647        futex_down(&async_futex);
    598648       
    599         if (--client->refcnt == 0) {
     649        if (atomic_predec(&client->refcnt) == 0) {
    600650                hash_table_remove(&client_hash_table, &key, 1);
    601651                destroy = true;
     
    616666         */
    617667        futex_down(&async_futex);
    618         key = FIBRIL_connection->in_phone_hash;
     668        key = fibril_connection->in_phone_hash;
    619669        hash_table_remove(&conn_hash_table, &key, 1);
    620670        futex_up(&async_futex);
     
    623673         * Answer all remaining messages with EHANGUP.
    624674         */
    625         while (!list_empty(&FIBRIL_connection->msg_queue)) {
     675        while (!list_empty(&fibril_connection->msg_queue)) {
    626676                msg_t *msg =
    627                     list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
    628                     link);
     677                    list_get_instance(list_first(&fibril_connection->msg_queue),
     678                    msg_t, link);
    629679               
    630680                list_remove(&msg->link);
     
    637687         * i.e. IPC_M_PHONE_HUNGUP.
    638688         */
    639         if (FIBRIL_connection->close_callid)
    640                 ipc_answer_0(FIBRIL_connection->close_callid, EOK);
    641        
    642         free(FIBRIL_connection);
     689        if (fibril_connection->close_callid)
     690                ipc_answer_0(fibril_connection->close_callid, EOK);
     691       
     692        free(fibril_connection);
    643693        return 0;
    644694}
     
    646696/** Create a new fibril for a new connection.
    647697 *
    648  * Create new fibril for connection, fill in connection structures and inserts
     698 * Create new fibril for connection, fill in connection structures and insert
    649699 * it into the hash table, so that later we can easily do routing of messages to
    650700 * particular fibrils.
     
    659709 * @param cfibril       Fibril function that should be called upon opening the
    660710 *                      connection.
     711 * @param carg          Extra argument to pass to the connection fibril
    661712 *
    662713 * @return New fibril id or NULL on failure.
     
    665716fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
    666717    ipc_callid_t callid, ipc_call_t *call,
    667     void (*cfibril)(ipc_callid_t, ipc_call_t *))
     718    async_client_conn_t cfibril, void *carg)
    668719{
    669720        connection_t *conn = malloc(sizeof(*conn));
     
    680731        conn->callid = callid;
    681732        conn->close_callid = 0;
     733        conn->carg = carg;
    682734       
    683735        if (call)
     
    721773static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    722774{
     775        assert(call);
     776       
    723777        /* Unrouted call - take some default action */
    724778        if ((callid & IPC_CALLID_NOTIFICATION)) {
     
    732786                /* Open new connection with fibril, etc. */
    733787                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
    734                     callid, call, client_connection);
     788                    callid, call, client_connection, NULL);
    735789                return;
    736790        }
     
    752806        futex_down(&async_futex);
    753807       
    754         link_t *cur = timeout_list.next;
    755         while (cur != &timeout_list) {
     808        link_t *cur = list_first(&timeout_list);
     809        while (cur != NULL) {
    756810                awaiter_t *waiter =
    757811                    list_get_instance(cur, awaiter_t, to_event.link);
     
    759813                if (tv_gt(&waiter->to_event.expires, &tv))
    760814                        break;
    761                
    762                 cur = cur->next;
    763815               
    764816                list_remove(&waiter->to_event.link);
     
    774826                        fibril_add_ready(waiter->fid);
    775827                }
     828               
     829                cur = list_first(&timeout_list);
    776830        }
    777831       
     
    800854                suseconds_t timeout;
    801855                if (!list_empty(&timeout_list)) {
    802                         awaiter_t *waiter = list_get_instance(timeout_list.next,
    803                             awaiter_t, to_event.link);
     856                        awaiter_t *waiter = list_get_instance(
     857                            list_first(&timeout_list), awaiter_t, to_event.link);
    804858                       
    805859                        struct timeval tv;
     
    878932void __async_init(void)
    879933{
    880         if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
    881             &client_hash_table_ops))
     934        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
     935            1, &client_hash_table_ops))
    882936                abort();
    883937       
    884         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
    885             &conn_hash_table_ops))
     938        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
     939            1, &conn_hash_table_ops))
    886940                abort();
     941       
     942        session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
     943        if (session_ns == NULL)
     944                abort();
     945       
     946        session_ns->mgmt = EXCHANGE_ATOMIC;
     947        session_ns->phone = PHONE_NS;
     948        session_ns->arg1 = 0;
     949        session_ns->arg2 = 0;
     950        session_ns->arg3 = 0;
     951       
     952        list_initialize(&session_ns->exch_list);
     953        fibril_mutex_initialize(&session_ns->mutex);
     954        atomic_set(&session_ns->refcnt, 0);
    887955}
    888956
     
    899967 *
    900968 */
    901 static void reply_received(void *arg, int retval, ipc_call_t *data)
    902 {
     969void reply_received(void *arg, int retval, ipc_call_t *data)
     970{
     971        assert(arg);
     972       
    903973        futex_down(&async_futex);
    904974       
     
    9301000 * completion.
    9311001 *
    932  * @param phoneid Handle of the phone that will be used for the send.
    933  * @param method  Service-defined method.
     1002 * @param exch    Exchange for sending the message.
     1003 * @param imethod Service-defined interface and method.
    9341004 * @param arg1    Service-defined payload argument.
    9351005 * @param arg2    Service-defined payload argument.
     
    9421012 *
    9431013 */
    944 aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1014aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9451015    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    9461016{
     1017        if (exch == NULL)
     1018                return 0;
     1019       
    9471020        amsg_t *msg = malloc(sizeof(amsg_t));
    948        
    949         if (!msg)
     1021        if (msg == NULL)
    9501022                return 0;
    9511023       
     
    9611033        msg->wdata.active = true;
    9621034       
    963         ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
     1035        ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
    9641036            reply_received, true);
    9651037       
     
    9721044 * completion.
    9731045 *
    974  * @param phoneid Handle of the phone that will be used for the send.
    975  * @param method  Service-defined method.
     1046 * @param exch    Exchange for sending the message.
     1047 * @param imethod Service-defined interface and method.
    9761048 * @param arg1    Service-defined payload argument.
    9771049 * @param arg2    Service-defined payload argument.
     
    9851057 *
    9861058 */
    987 aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1059aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9881060    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    9891061    ipc_call_t *dataptr)
    9901062{
     1063        if (exch == NULL)
     1064                return 0;
     1065       
    9911066        amsg_t *msg = malloc(sizeof(amsg_t));
    9921067       
    993         if (!msg)
     1068        if (msg == NULL)
    9941069                return 0;
    9951070       
     
    10051080        msg->wdata.active = true;
    10061081       
    1007         ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
    1008             reply_received, true);
     1082        ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
     1083            msg, reply_received, true);
    10091084       
    10101085        return (aid_t) msg;
     
    10201095void async_wait_for(aid_t amsgid, sysarg_t *retval)
    10211096{
     1097        assert(amsgid);
     1098       
    10221099        amsg_t *msg = (amsg_t *) amsgid;
    10231100       
     
    10561133int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)
    10571134{
     1135        assert(amsgid);
     1136       
    10581137        amsg_t *msg = (amsg_t *) amsgid;
    10591138       
     
    11241203}
    11251204
    1126 /** Setter for client_connection function pointer.
    1127  *
    1128  * @param conn Function that will implement a new connection fibril.
    1129  *
    1130  */
    1131 void async_set_client_connection(async_client_conn_t conn)
    1132 {
    1133         client_connection = conn;
    1134 }
    1135 
    1136 /** Setter for interrupt_received function pointer.
    1137  *
    1138  * @param intr Function that will implement a new interrupt
    1139  *             notification fibril.
    1140  */
    1141 void async_set_interrupt_received(async_client_conn_t intr)
    1142 {
    1143         interrupt_received = intr;
    1144 }
    1145 
    11461205/** Pseudo-synchronous message sending - fast version.
    11471206 *
     
    11511210 * transferring more arguments, see the slower async_req_slow().
    11521211 *
    1153  * @param phoneid Hash of the phone through which to make the call.
    1154  * @param method  Method of the call.
     1212 * @param exch    Exchange for sending the message.
     1213 * @param imethod Interface and method of the call.
    11551214 * @param arg1    Service-defined payload argument.
    11561215 * @param arg2    Service-defined payload argument.
     
    11661225 *
    11671226 */
    1168 sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1227sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    11691228    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    11701229    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    11711230{
     1231        if (exch == NULL)
     1232                return ENOENT;
     1233       
    11721234        ipc_call_t result;
    1173         aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
     1235        aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
    11741236            &result);
    11751237       
    11761238        sysarg_t rc;
    1177         async_wait_for(eid, &rc);
     1239        async_wait_for(aid, &rc);
    11781240       
    11791241        if (r1)
     
    11991261 * Send message asynchronously and return only after the reply arrives.
    12001262 *
    1201  * @param phoneid Hash of the phone through which to make the call.
    1202  * @param method  Method of the call.
     1263 * @param exch    Exchange for sending the message.
     1264 * @param imethod Interface and method of the call.
    12031265 * @param arg1    Service-defined payload argument.
    12041266 * @param arg2    Service-defined payload argument.
     
    12151277 *
    12161278 */
    1217 sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1279sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    12181280    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    12191281    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    12201282{
     1283        if (exch == NULL)
     1284                return ENOENT;
     1285       
    12211286        ipc_call_t result;
    1222         aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
     1287        aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5,
    12231288            &result);
    12241289       
    12251290        sysarg_t rc;
    1226         async_wait_for(eid, &rc);
     1291        async_wait_for(aid, &rc);
    12271292       
    12281293        if (r1)
     
    12441309}
    12451310
    1246 void async_msg_0(int phone, sysarg_t imethod)
    1247 {
    1248         ipc_call_async_0(phone, imethod, NULL, NULL, true);
    1249 }
    1250 
    1251 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
    1252 {
    1253         ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
    1254 }
    1255 
    1256 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
    1257 {
    1258         ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
    1259 }
    1260 
    1261 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1262     sysarg_t arg3)
    1263 {
    1264         ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
    1265 }
    1266 
    1267 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1268     sysarg_t arg3, sysarg_t arg4)
    1269 {
    1270         ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
    1271             true);
    1272 }
    1273 
    1274 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1275     sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    1276 {
    1277         ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
    1278             NULL, true);
     1311void async_msg_0(async_exch_t *exch, sysarg_t imethod)
     1312{
     1313        if (exch != NULL)
     1314                ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
     1315}
     1316
     1317void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
     1318{
     1319        if (exch != NULL)
     1320                ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
     1321}
     1322
     1323void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1324    sysarg_t arg2)
     1325{
     1326        if (exch != NULL)
     1327                ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
     1328                    true);
     1329}
     1330
     1331void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1332    sysarg_t arg2, sysarg_t arg3)
     1333{
     1334        if (exch != NULL)
     1335                ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
     1336                    NULL, true);
     1337}
     1338
     1339void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1340    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1341{
     1342        if (exch != NULL)
     1343                ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1344                    NULL, NULL, true);
     1345}
     1346
     1347void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1348    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1349{
     1350        if (exch != NULL)
     1351                ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1352                    arg5, NULL, NULL, true);
    12791353}
    12801354
     
    13131387}
    13141388
    1315 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1316     sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    1317 {
    1318         return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
    1319 }
    1320 
    1321 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1322     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    1323     unsigned int mode)
    1324 {
    1325         return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
    1326             arg5, mode);
     1389int async_forward_fast(ipc_callid_t callid, async_exch_t *exch,
     1390    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1391{
     1392        if (exch == NULL)
     1393                return ENOENT;
     1394       
     1395        return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode);
     1396}
     1397
     1398int async_forward_slow(ipc_callid_t callid, async_exch_t *exch,
     1399    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     1400    sysarg_t arg4, sysarg_t arg5, unsigned int mode)
     1401{
     1402        if (exch == NULL)
     1403                return ENOENT;
     1404       
     1405        return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3,
     1406            arg4, arg5, mode);
    13271407}
    13281408
     
    13311411 * Ask through phone for a new connection to some service.
    13321412 *
    1333  * @param phone           Phone handle used for contacting the other side.
     1413 * @param exch            Exchange for sending the message.
    13341414 * @param arg1            User defined argument.
    13351415 * @param arg2            User defined argument.
     
    13371417 * @param client_receiver Connection handing routine.
    13381418 *
    1339  * @return New phone handle on success or a negative error code.
    1340  *
    1341  */
    1342 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
    1343     sysarg_t arg3, async_client_conn_t client_receiver)
    1344 {
     1419 * @return Zero on success or a negative error code.
     1420 *
     1421 */
     1422int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     1423    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
     1424{
     1425        if (exch == NULL)
     1426                return ENOENT;
     1427       
    13451428        sysarg_t task_hash;
    13461429        sysarg_t phone_hash;
    1347         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1430        int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    13481431            NULL, NULL, NULL, &task_hash, &phone_hash);
    13491432        if (rc != EOK)
     
    13521435        if (client_receiver != NULL)
    13531436                async_new_connection(task_hash, phone_hash, 0, NULL,
    1354                     client_receiver);
     1437                    client_receiver, carg);
    13551438       
    13561439        return EOK;
    13571440}
    13581441
    1359 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1360  *
    1361  * Ask through phone for a new connection to some service.
    1362  *
    1363  * @param phone Phone handle used for contacting the other side.
    1364  * @param arg1  User defined argument.
    1365  * @param arg2  User defined argument.
    1366  * @param arg3  User defined argument.
    1367  *
    1368  * @return New phone handle on success or a negative error code.
    1369  *
    1370  */
    1371 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
    1372     sysarg_t arg3)
    1373 {
    1374         sysarg_t newphid;
    1375         int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    1376             NULL, NULL, NULL, NULL, &newphid);
     1442/** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
     1443 *
     1444 * Ask through for a cloned connection to some service.
     1445 *
     1446 * @param mgmt Exchange management style.
     1447 * @param exch Exchange for sending the message.
     1448 *
     1449 * @return New session on success or NULL on error.
     1450 *
     1451 */
     1452async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
     1453{
     1454        if (exch == NULL) {
     1455                errno = ENOENT;
     1456                return NULL;
     1457        }
     1458       
     1459        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1460        if (sess == NULL) {
     1461                errno = ENOMEM;
     1462                return NULL;
     1463        }
     1464       
     1465        ipc_call_t result;
     1466       
     1467        amsg_t *msg = malloc(sizeof(amsg_t));
     1468        if (msg == NULL) {
     1469                free(sess);
     1470                errno = ENOMEM;
     1471                return NULL;
     1472        }
     1473       
     1474        msg->done = false;
     1475        msg->dataptr = &result;
     1476       
     1477        msg->wdata.to_event.inlist = false;
     1478       
     1479        /*
     1480         * We may sleep in the next method,
     1481         * but it will use its own means
     1482         */
     1483        msg->wdata.active = true;
     1484       
     1485        ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
     1486            reply_received, true);
     1487       
     1488        sysarg_t rc;
     1489        async_wait_for((aid_t) msg, &rc);
     1490       
     1491        if (rc != EOK) {
     1492                errno = rc;
     1493                free(sess);
     1494                return NULL;
     1495        }
     1496       
     1497        int phone = (int) IPC_GET_ARG5(result);
     1498       
     1499        if (phone < 0) {
     1500                errno = phone;
     1501                free(sess);
     1502                return NULL;
     1503        }
     1504       
     1505        sess->mgmt = mgmt;
     1506        sess->phone = phone;
     1507        sess->arg1 = 0;
     1508        sess->arg2 = 0;
     1509        sess->arg3 = 0;
     1510       
     1511        list_initialize(&sess->exch_list);
     1512        fibril_mutex_initialize(&sess->mutex);
     1513        atomic_set(&sess->refcnt, 0);
     1514       
     1515        return sess;
     1516}
     1517
     1518static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2,
     1519    sysarg_t arg3, sysarg_t arg4)
     1520{
     1521        ipc_call_t result;
     1522       
     1523        amsg_t *msg = malloc(sizeof(amsg_t));
     1524        if (msg == NULL)
     1525                return ENOENT;
     1526       
     1527        msg->done = false;
     1528        msg->dataptr = &result;
     1529       
     1530        msg->wdata.to_event.inlist = false;
     1531       
     1532        /*
     1533         * We may sleep in the next method,
     1534         * but it will use its own means
     1535         */
     1536        msg->wdata.active = true;
     1537       
     1538        ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
     1539            msg, reply_received, true);
     1540       
     1541        sysarg_t rc;
     1542        async_wait_for((aid_t) msg, &rc);
    13771543       
    13781544        if (rc != EOK)
    13791545                return rc;
    13801546       
    1381         return newphid;
     1547        return (int) IPC_GET_ARG5(result);
     1548}
     1549
     1550/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1551 *
     1552 * Ask through for a new connection to some service.
     1553 *
     1554 * @param mgmt Exchange management style.
     1555 * @param exch Exchange for sending the message.
     1556 * @param arg1 User defined argument.
     1557 * @param arg2 User defined argument.
     1558 * @param arg3 User defined argument.
     1559 *
     1560 * @return New session on success or NULL on error.
     1561 *
     1562 */
     1563async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch,
     1564    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1565{
     1566        if (exch == NULL) {
     1567                errno = ENOENT;
     1568                return NULL;
     1569        }
     1570       
     1571        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1572        if (sess == NULL) {
     1573                errno = ENOMEM;
     1574                return NULL;
     1575        }
     1576       
     1577        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1578            0);
     1579       
     1580        if (phone < 0) {
     1581                errno = phone;
     1582                free(sess);
     1583                return NULL;
     1584        }
     1585       
     1586        sess->mgmt = mgmt;
     1587        sess->phone = phone;
     1588        sess->arg1 = arg1;
     1589        sess->arg2 = arg2;
     1590        sess->arg3 = arg3;
     1591       
     1592        list_initialize(&sess->exch_list);
     1593        fibril_mutex_initialize(&sess->mutex);
     1594        atomic_set(&sess->refcnt, 0);
     1595       
     1596        return sess;
    13821597}
    13831598
     
    13871602 * success.
    13881603 *
    1389  * @param phoneid Phone handle used for contacting the other side.
    1390  * @param arg1    User defined argument.
    1391  * @param arg2    User defined argument.
    1392  * @param arg3    User defined argument.
    1393  *
    1394  * @return New phone handle on success or a negative error code.
    1395  *
    1396  */
    1397 int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    1398     sysarg_t arg3)
    1399 {
    1400         sysarg_t newphid;
    1401         int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    1402             IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    1403        
    1404         if (rc != EOK)
    1405                 return rc;
    1406        
    1407         return newphid;
     1604 * @param mgmt Exchange management style.
     1605 * @param exch Exchange for sending the message.
     1606 * @param arg1 User defined argument.
     1607 * @param arg2 User defined argument.
     1608 * @param arg3 User defined argument.
     1609 *
     1610 * @return New session on success or NULL on error.
     1611 *
     1612 */
     1613async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch,
     1614    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1615{
     1616        if (exch == NULL) {
     1617                errno = ENOENT;
     1618                return NULL;
     1619        }
     1620       
     1621        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1622        if (sess == NULL) {
     1623                errno = ENOMEM;
     1624                return NULL;
     1625        }
     1626       
     1627        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1628            IPC_FLAG_BLOCKING);
     1629       
     1630        if (phone < 0) {
     1631                errno = phone;
     1632                free(sess);
     1633                return NULL;
     1634        }
     1635       
     1636        sess->mgmt = mgmt;
     1637        sess->phone = phone;
     1638        sess->arg1 = arg1;
     1639        sess->arg2 = arg2;
     1640        sess->arg3 = arg3;
     1641       
     1642        list_initialize(&sess->exch_list);
     1643        fibril_mutex_initialize(&sess->mutex);
     1644        atomic_set(&sess->refcnt, 0);
     1645       
     1646        return sess;
    14081647}
    14091648
     
    14111650 *
    14121651 */
    1413 int async_connect_kbox(task_id_t id)
    1414 {
    1415         return ipc_connect_kbox(id);
     1652async_sess_t *async_connect_kbox(task_id_t id)
     1653{
     1654        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1655        if (sess == NULL) {
     1656                errno = ENOMEM;
     1657                return NULL;
     1658        }
     1659       
     1660        int phone = ipc_connect_kbox(id);
     1661        if (phone < 0) {
     1662                errno = phone;
     1663                free(sess);
     1664                return NULL;
     1665        }
     1666       
     1667        sess->mgmt = EXCHANGE_ATOMIC;
     1668        sess->phone = phone;
     1669        sess->arg1 = 0;
     1670        sess->arg2 = 0;
     1671        sess->arg3 = 0;
     1672       
     1673        list_initialize(&sess->exch_list);
     1674        fibril_mutex_initialize(&sess->mutex);
     1675        atomic_set(&sess->refcnt, 0);
     1676       
     1677        return sess;
     1678}
     1679
     1680static int async_hangup_internal(int phone)
     1681{
     1682        return ipc_hangup(phone);
    14161683}
    14171684
    14181685/** Wrapper for ipc_hangup.
    14191686 *
    1420  * @param phone Phone handle to hung up.
     1687 * @param sess Session to hung up.
    14211688 *
    14221689 * @return Zero on success or a negative error code.
    14231690 *
    14241691 */
    1425 int async_hangup(int phone)
    1426 {
    1427         return ipc_hangup(phone);
     1692int async_hangup(async_sess_t *sess)
     1693{
     1694        assert(sess);
     1695       
     1696        if (atomic_get(&sess->refcnt) > 0)
     1697                return EBUSY;
     1698       
     1699        int rc = async_hangup_internal(sess->phone);
     1700        if (rc == EOK)
     1701                free(sess);
     1702       
     1703        return rc;
    14281704}
    14291705
     
    14341710}
    14351711
     1712/** Start new exchange in a session.
     1713 *
     1714 * @param session Session.
     1715 *
     1716 * @return New exchange or NULL on error.
     1717 *
     1718 */
     1719async_exch_t *async_exchange_begin(async_sess_t *sess)
     1720{
     1721        if (sess == NULL)
     1722                return NULL;
     1723       
     1724        async_exch_t *exch;
     1725       
     1726        fibril_mutex_lock(&async_sess_mutex);
     1727       
     1728        if (!list_empty(&sess->exch_list)) {
     1729                /*
     1730                 * There are inactive exchanges in the session.
     1731                 */
     1732                exch = (async_exch_t *)
     1733                    list_get_instance(list_first(&sess->exch_list),
     1734                    async_exch_t, sess_link);
     1735               
     1736                list_remove(&exch->sess_link);
     1737                list_remove(&exch->global_link);
     1738        } else {
     1739                /*
     1740                 * There are no available exchanges in the session.
     1741                 */
     1742               
     1743                if ((sess->mgmt == EXCHANGE_ATOMIC) ||
     1744                    (sess->mgmt == EXCHANGE_SERIALIZE)) {
     1745                        exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1746                        if (exch != NULL) {
     1747                                link_initialize(&exch->sess_link);
     1748                                link_initialize(&exch->global_link);
     1749                                exch->sess = sess;
     1750                                exch->phone = sess->phone;
     1751                        }
     1752                } else {  /* EXCHANGE_PARALLEL */
     1753                        /*
     1754                         * Make a one-time attempt to connect a new data phone.
     1755                         */
     1756                       
     1757                        int phone;
     1758                       
     1759retry:
     1760                        phone = async_connect_me_to_internal(sess->phone, sess->arg1,
     1761                            sess->arg2, sess->arg3, 0);
     1762                        if (phone >= 0) {
     1763                                exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1764                                if (exch != NULL) {
     1765                                        link_initialize(&exch->sess_link);
     1766                                        link_initialize(&exch->global_link);
     1767                                        exch->sess = sess;
     1768                                        exch->phone = phone;
     1769                                } else
     1770                                        async_hangup_internal(phone);
     1771                        } else if (!list_empty(&inactive_exch_list)) {
     1772                                /*
     1773                                 * We did not manage to connect a new phone. But we
     1774                                 * can try to close some of the currently inactive
     1775                                 * connections in other sessions and try again.
     1776                                 */
     1777                                exch = (async_exch_t *)
     1778                                    list_get_instance(list_first(&inactive_exch_list),
     1779                                    async_exch_t, global_link);
     1780                               
     1781                                list_remove(&exch->sess_link);
     1782                                list_remove(&exch->global_link);
     1783                                async_hangup_internal(exch->phone);
     1784                                free(exch);
     1785                                goto retry;
     1786                        } else {
     1787                                /*
     1788                                 * Wait for a phone to become available.
     1789                                 */
     1790                                fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
     1791                                goto retry;
     1792                        }
     1793                }
     1794        }
     1795       
     1796        fibril_mutex_unlock(&async_sess_mutex);
     1797       
     1798        if (exch != NULL) {
     1799                atomic_inc(&sess->refcnt);
     1800               
     1801                if (sess->mgmt == EXCHANGE_SERIALIZE)
     1802                        fibril_mutex_lock(&sess->mutex);
     1803        }
     1804       
     1805        return exch;
     1806}
     1807
     1808/** Finish an exchange.
     1809 *
     1810 * @param exch Exchange to finish.
     1811 *
     1812 */
     1813void async_exchange_end(async_exch_t *exch)
     1814{
     1815        if (exch == NULL)
     1816                return;
     1817       
     1818        async_sess_t *sess = exch->sess;
     1819       
     1820        atomic_dec(&sess->refcnt);
     1821       
     1822        if (sess->mgmt == EXCHANGE_SERIALIZE)
     1823                fibril_mutex_unlock(&sess->mutex);
     1824       
     1825        fibril_mutex_lock(&async_sess_mutex);
     1826       
     1827        list_append(&exch->sess_link, &sess->exch_list);
     1828        list_append(&exch->global_link, &inactive_exch_list);
     1829        fibril_condvar_signal(&avail_phone_cv);
     1830       
     1831        fibril_mutex_unlock(&async_sess_mutex);
     1832}
     1833
    14361834/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
    14371835 *
    1438  * @param phoneid Phone that will be used to contact the receiving side.
    1439  * @param dst     Destination address space area base.
    1440  * @param size    Size of the destination address space area.
    1441  * @param arg     User defined argument.
    1442  * @param flags   Storage for the received flags. Can be NULL.
     1836 * @param exch  Exchange for sending the message.
     1837 * @param dst   Destination address space area base.
     1838 * @param size  Size of the destination address space area.
     1839 * @param arg   User defined argument.
     1840 * @param flags Storage for the received flags. Can be NULL.
    14431841 *
    14441842 * @return Zero on success or a negative error code from errno.h.
    14451843 *
    14461844 */
    1447 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1448     unsigned int *flags)
    1449 {
     1845int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
     1846    sysarg_t arg, unsigned int *flags)
     1847{
     1848        if (exch == NULL)
     1849                return ENOENT;
     1850       
    14501851        sysarg_t tmp_flags;
    1451         int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1852        int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
    14521853            (sysarg_t) size, arg, NULL, &tmp_flags);
    14531854       
     
    15071908/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
    15081909 *
    1509  * @param phoneid Phone that will be used to contact the receiving side.
    1510  * @param src     Source address space area base address.
    1511  * @param flags   Flags to be used for sharing. Bits can be only cleared.
     1910 * @param exch  Exchange for sending the message.
     1911 * @param src   Source address space area base address.
     1912 * @param flags Flags to be used for sharing. Bits can be only cleared.
    15121913 *
    15131914 * @return Zero on success or a negative error code from errno.h.
    15141915 *
    15151916 */
    1516 int async_share_out_start(int phoneid, void *src, unsigned int flags)
    1517 {
    1518         return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     1917int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags)
     1918{
     1919        if (exch == NULL)
     1920                return ENOENT;
     1921       
     1922        return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
    15191923            (sysarg_t) flags);
    15201924}
     
    15691973}
    15701974
     1975/** Start IPC_M_DATA_READ using the async framework.
     1976 *
     1977 * @param exch    Exchange for sending the message.
     1978 * @param dst     Address of the beginning of the destination buffer.
     1979 * @param size    Size of the destination buffer (in bytes).
     1980 * @param dataptr Storage of call data (arg 2 holds actual data size).
     1981 *
     1982 * @return Hash of the sent message or 0 on error.
     1983 *
     1984 */
     1985aid_t async_data_read(async_exch_t *exch, void *dst, size_t size,
     1986    ipc_call_t *dataptr)
     1987{
     1988        return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst,
     1989            (sysarg_t) size, dataptr);
     1990}
     1991
    15711992/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15721993 *
    1573  * @param phoneid Phone that will be used to contact the receiving side.
    1574  * @param dst     Address of the beginning of the destination buffer.
    1575  * @param size    Size of the destination buffer.
    1576  * @param flags   Flags to control the data transfer.
     1994 * @param exch Exchange for sending the message.
     1995 * @param dst  Address of the beginning of the destination buffer.
     1996 * @param size Size of the destination buffer.
    15771997 *
    15781998 * @return Zero on success or a negative error code from errno.h.
    15791999 *
    15802000 */
    1581 int
    1582 async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags)
    1583 {
    1584         return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
    1585             (sysarg_t) size, (sysarg_t) flags);
     2001int async_data_read_start(async_exch_t *exch, void *dst, size_t size)
     2002{
     2003        if (exch == NULL)
     2004                return ENOENT;
     2005       
     2006        return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst,
     2007            (sysarg_t) size);
    15862008}
    15872009
     
    16382060 *
    16392061 */
    1640 int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    1641     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    1642 {
     2062int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2063    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2064    ipc_call_t *dataptr)
     2065{
     2066        if (exch == NULL)
     2067                return ENOENT;
     2068       
    16432069        ipc_callid_t callid;
    16442070        if (!async_data_read_receive(&callid, NULL)) {
     
    16472073        }
    16482074       
    1649         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2075        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    16502076            dataptr);
    16512077        if (msg == 0) {
     
    16542080        }
    16552081       
    1656         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2082        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    16572083            IPC_FF_ROUTE_FROM_ME);
    16582084        if (retval != EOK) {
     
    16702096/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    16712097 *
    1672  * @param phoneid Phone that will be used to contact the receiving side.
    1673  * @param src     Address of the beginning of the source buffer.
    1674  * @param size    Size of the source buffer.
    1675  * @param flags   Flags to control the data transfer.
     2098 * @param exch Exchange for sending the message.
     2099 * @param src  Address of the beginning of the source buffer.
     2100 * @param size Size of the source buffer.
    16762101 *
    16772102 * @return Zero on success or a negative error code from errno.h.
    16782103 *
    16792104 */
    1680 int
    1681 async_data_write_start_generic(int phoneid, const void *src, size_t size,
    1682     int flags)
    1683 {
    1684         return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
    1685             (sysarg_t) size, (sysarg_t) flags);
     2105int async_data_write_start(async_exch_t *exch, const void *src, size_t size)
     2106{
     2107        if (exch == NULL)
     2108                return ENOENT;
     2109       
     2110        return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src,
     2111            (sysarg_t) size);
    16862112}
    16872113
     
    17592185    size_t *received)
    17602186{
     2187        assert(data);
     2188       
    17612189        ipc_callid_t callid;
    17622190        size_t size;
     
    18262254 *
    18272255 */
    1828 int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    1829     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    1830 {
     2256int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2257    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2258    ipc_call_t *dataptr)
     2259{
     2260        if (exch == NULL)
     2261                return ENOENT;
     2262       
    18312263        ipc_callid_t callid;
    18322264        if (!async_data_write_receive(&callid, NULL)) {
     
    18352267        }
    18362268       
    1837         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2269        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    18382270            dataptr);
    18392271        if (msg == 0) {
     
    18422274        }
    18432275       
    1844         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2276        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    18452277            IPC_FF_ROUTE_FROM_ME);
    18462278        if (retval != EOK) {
     
    18562288}
    18572289
     2290/** Wrapper for sending an exchange over different exchange for cloning
     2291 *
     2292 * @param exch       Exchange to be used for sending.
     2293 * @param clone_exch Exchange to be cloned.
     2294 *
     2295 */
     2296int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
     2297{
     2298        return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
     2299}
     2300
     2301/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
     2302 *
     2303 * If the current call is IPC_M_CONNECTION_CLONE then a new
     2304 * async session is created for the accepted phone.
     2305 *
     2306 * @param mgmt Exchange management style.
     2307 *
     2308 * @return New async session or NULL on failure.
     2309 *
     2310 */
     2311async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
     2312{
     2313        /* Accept the phone */
     2314        ipc_call_t call;
     2315        ipc_callid_t callid = async_get_call(&call);
     2316        int phone = (int) IPC_GET_ARG1(call);
     2317       
     2318        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
     2319            (phone < 0)) {
     2320                async_answer_0(callid, EINVAL);
     2321                return NULL;
     2322        }
     2323       
     2324        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2325        if (sess == NULL) {
     2326                async_answer_0(callid, ENOMEM);
     2327                return NULL;
     2328        }
     2329       
     2330        sess->mgmt = mgmt;
     2331        sess->phone = phone;
     2332        sess->arg1 = 0;
     2333        sess->arg2 = 0;
     2334        sess->arg3 = 0;
     2335       
     2336        list_initialize(&sess->exch_list);
     2337        fibril_mutex_initialize(&sess->mutex);
     2338        atomic_set(&sess->refcnt, 0);
     2339       
     2340        /* Acknowledge the cloned phone */
     2341        async_answer_0(callid, EOK);
     2342       
     2343        return sess;
     2344}
     2345
     2346/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
     2347 *
     2348 * If the current call is IPC_M_CONNECT_TO_ME then a new
     2349 * async session is created for the accepted phone.
     2350 *
     2351 * @param mgmt Exchange management style.
     2352 *
     2353 * @return New async session.
     2354 * @return NULL on failure.
     2355 *
     2356 */
     2357async_sess_t *async_callback_receive(exch_mgmt_t mgmt)
     2358{
     2359        /* Accept the phone */
     2360        ipc_call_t call;
     2361        ipc_callid_t callid = async_get_call(&call);
     2362        int phone = (int) IPC_GET_ARG5(call);
     2363       
     2364        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
     2365            (phone < 0)) {
     2366                async_answer_0(callid, EINVAL);
     2367                return NULL;
     2368        }
     2369       
     2370        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2371        if (sess == NULL) {
     2372                async_answer_0(callid, ENOMEM);
     2373                return NULL;
     2374        }
     2375       
     2376        sess->mgmt = mgmt;
     2377        sess->phone = phone;
     2378        sess->arg1 = 0;
     2379        sess->arg2 = 0;
     2380        sess->arg3 = 0;
     2381       
     2382        list_initialize(&sess->exch_list);
     2383        fibril_mutex_initialize(&sess->mutex);
     2384        atomic_set(&sess->refcnt, 0);
     2385       
     2386        /* Acknowledge the connected phone */
     2387        async_answer_0(callid, EOK);
     2388       
     2389        return sess;
     2390}
     2391
     2392/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
     2393 *
     2394 * If the call is IPC_M_CONNECT_TO_ME then a new
     2395 * async session is created. However, the phone is
     2396 * not accepted automatically.
     2397 *
     2398 * @param mgmt   Exchange management style.
     2399 * @param call   Call data.
     2400 *
     2401 * @return New async session.
     2402 * @return NULL on failure.
     2403 * @return NULL if the call is not IPC_M_CONNECT_TO_ME.
     2404 *
     2405 */
     2406async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call)
     2407{
     2408        int phone = (int) IPC_GET_ARG5(*call);
     2409       
     2410        if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) ||
     2411            (phone < 0))
     2412                return NULL;
     2413       
     2414        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2415        if (sess == NULL)
     2416                return NULL;
     2417       
     2418        sess->mgmt = mgmt;
     2419        sess->phone = phone;
     2420        sess->arg1 = 0;
     2421        sess->arg2 = 0;
     2422        sess->arg3 = 0;
     2423       
     2424        list_initialize(&sess->exch_list);
     2425        fibril_mutex_initialize(&sess->mutex);
     2426        atomic_set(&sess->refcnt, 0);
     2427       
     2428        return sess;
     2429}
     2430
    18582431/** @}
    18592432 */
  • uspace/lib/c/generic/clipboard.c

    r52a79081 ra33f0a6  
    3939
    4040#include <clipboard.h>
    41 #include <ipc/ns.h>
     41#include <ns.h>
    4242#include <ipc/services.h>
    4343#include <ipc/clipboard.h>
     44#include <fibril_synch.h>
    4445#include <async.h>
    4546#include <str.h>
     
    4748#include <malloc.h>
    4849
    49 static int clip_phone = -1;
    50 
    51 /** Connect to clipboard server
    52  *
    53  */
    54 static void clip_connect(void)
    55 {
    56         while (clip_phone < 0)
    57                 clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
     50static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
     51static async_sess_t *clip_sess = NULL;
     52
     53/** Start an async exchange on the clipboard session.
     54 *
     55 * @return New exchange.
     56 *
     57 */
     58static async_exch_t *clip_exchange_begin(void)
     59{
     60        fibril_mutex_lock(&clip_mutex);
     61       
     62        while (clip_sess == NULL)
     63                clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     64                    SERVICE_CLIPBOARD, 0, 0);
     65       
     66        fibril_mutex_unlock(&clip_mutex);
     67       
     68        return async_exchange_begin(clip_sess);
     69}
     70
     71/** Finish an async exchange on the clipboard session.
     72 *
     73 * @param exch Exchange to be finished.
     74 *
     75 */
     76static void clip_exchange_end(async_exch_t *exch)
     77{
     78        async_exchange_end(exch);
    5879}
    5980
     
    7394       
    7495        if (size == 0) {
    75                 async_serialize_start();
    76                 clip_connect();
    77                
    78                 sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
    79                
    80                 async_serialize_end();
     96                async_exch_t *exch = clip_exchange_begin();
     97                sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
     98                    CLIPBOARD_TAG_NONE);
     99                clip_exchange_end(exch);
    81100               
    82101                return (int) rc;
    83102        } else {
    84                 async_serialize_start();
    85                 clip_connect();
    86                
    87                 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
    88                 sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
     103                async_exch_t *exch = clip_exchange_begin();
     104                aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
     105                    NULL);
     106                sysarg_t rc = async_data_write_start(exch, (void *) str, size);
     107                clip_exchange_end(exch);
     108               
    89109                if (rc != EOK) {
    90110                        sysarg_t rc_orig;
    91111                        async_wait_for(req, &rc_orig);
    92                         async_serialize_end();
    93112                        if (rc_orig == EOK)
    94113                                return (int) rc;
     
    98117               
    99118                async_wait_for(req, &rc);
    100                 async_serialize_end();
    101119               
    102120                return (int) rc;
     
    117135        /* Loop until clipboard read succesful */
    118136        while (true) {
    119                 async_serialize_start();
    120                 clip_connect();
     137                async_exch_t *exch = clip_exchange_begin();
    121138               
    122139                sysarg_t size;
    123140                sysarg_t tag;
    124                 sysarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
    125                
    126                 async_serialize_end();
     141                sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
     142               
     143                clip_exchange_end(exch);
    127144               
    128145                if (rc != EOK)
     
    145162                                return ENOMEM;
    146163                       
    147                         async_serialize_start();
    148                        
    149                         aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
    150                         rc = async_data_read_start(clip_phone, (void *) sbuf, size);
     164                        exch = clip_exchange_begin();
     165                        aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
     166                        rc = async_data_read_start(exch, (void *) sbuf, size);
     167                        clip_exchange_end(exch);
     168                       
    151169                        if ((int) rc == EOVERFLOW) {
    152170                                /*
     
    154172                                 * the last call of CLIPBOARD_CONTENT
    155173                                 */
    156                                 async_serialize_end();
    157174                                break;
    158175                        }
     
    161178                                sysarg_t rc_orig;
    162179                                async_wait_for(req, &rc_orig);
    163                                 async_serialize_end();
    164180                                if (rc_orig == EOK)
    165181                                        return (int) rc;
     
    169185                       
    170186                        async_wait_for(req, &rc);
    171                         async_serialize_end();
    172187                       
    173188                        if (rc == EOK) {
  • uspace/lib/c/generic/device/char_dev.c

    r52a79081 ra33f0a6  
    4545 * using its character interface.
    4646 *
    47  * @param dev_phone     Phone to the device.
    48  * @param buf           Buffer for the data read from or written to the device.
    49  * @param size          Maximum size of data (in bytes) to be read or written.
    50  * @param read          Read from the device if true, write to it otherwise.
     47 * @param sess Session to the device.
     48 * @param buf  Buffer for the data read from or written to the device.
     49 * @param size Maximum size of data (in bytes) to be read or written.
     50 * @param read Read from the device if true, write to it otherwise.
    5151 *
    52  * @return              Non-negative number of bytes actually read from or
    53  *                      written to the device on success, negative error number
    54  *                      otherwise.
     52 * @return Non-negative number of bytes actually read from or
     53 *         written to the device on success, negative error number
     54 *         otherwise.
     55 *
    5556 */
    56 static ssize_t char_dev_rw(int dev_phone, void *buf, size_t size, bool read)
     57static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
    5758{
    58         async_serialize_start();
    59        
    6059        ipc_call_t answer;
    6160        aid_t req;
    6261        int ret;
    6362       
     63        async_exch_t *exch = async_exchange_begin(sess);
     64       
    6465        if (read) {
    65                 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
     66                req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
    6667                    CHAR_DEV_READ, &answer);
    67                 ret = async_data_read_start(dev_phone, buf, size);
     68                ret = async_data_read_start(exch, buf, size);
    6869        } else {
    69                 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
     70                req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
    7071                    CHAR_DEV_WRITE, &answer);
    71                 ret = async_data_write_start(dev_phone, buf, size);
     72                ret = async_data_write_start(exch, buf, size);
    7273        }
     74       
     75        async_exchange_end(exch);
    7376       
    7477        sysarg_t rc;
    7578        if (ret != EOK) {
    7679                async_wait_for(req, &rc);
    77                 async_serialize_end();
    7880                if (rc == EOK)
    7981                        return (ssize_t) ret;
     
    8385       
    8486        async_wait_for(req, &rc);
    85         async_serialize_end();
    8687       
    8788        ret = (int) rc;
     
    9495/** Read from character device.
    9596 *
    96  * @param dev_phone     Phone to the device.
    97  * @param buf           Output buffer for the data read from the device.
    98  * @param size          Maximum size (in bytes) of the data to be read.
     97 * @param sess Session to the device.
     98 * @param buf  Output buffer for the data read from the device.
     99 * @param size Maximum size (in bytes) of the data to be read.
    99100 *
    100  * @return              Non-negative number of bytes actually read from the
    101  *                      device on success, negative error number otherwise.
     101 * @return Non-negative number of bytes actually read from the
     102 *         device on success, negative error number otherwise.
     103 *
    102104 */
    103 ssize_t char_dev_read(int dev_phone, void *buf, size_t size)
     105ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
    104106{
    105         return char_dev_rw(dev_phone, buf, size, true);
     107        return char_dev_rw(sess, buf, size, true);
    106108}
    107109
    108110/** Write to character device.
    109111 *
    110  * @param dev_phone     Phone to the device.
    111  * @param buf           Input buffer containg the data to be written to the
    112  *                      device.
    113  * @param size          Maximum size (in bytes) of the data to be written.
     112 * @param sess Session to the device.
     113 * @param buf  Input buffer containg the data to be written to the
     114 *             device.
     115 * @param size Maximum size (in bytes) of the data to be written.
    114116 *
    115  * @return              Non-negative number of bytes actually written to the
    116  *                      device on success, negative error number otherwise.
     117 * @return Non-negative number of bytes actually written to the
     118 *         device on success, negative error number otherwise.
     119 *
    117120 */
    118 ssize_t char_dev_write(int dev_phone, void *buf, size_t size)
     121ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
    119122{
    120         return char_dev_rw(dev_phone, buf, size, false);
     123        return char_dev_rw(sess, buf, size, false);
    121124}
    122125
  • uspace/lib/c/generic/device/hw_res.c

    r52a79081 ra33f0a6  
    3838#include <malloc.h>
    3939
    40 int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources)
     40int hw_res_get_resource_list(async_sess_t *sess,
     41    hw_resource_list_t *hw_resources)
    4142{
    4243        sysarg_t count = 0;
    43 
    44         int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
     44       
     45        async_exch_t *exch = async_exchange_begin(sess);
     46        int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
    4547            HW_RES_GET_RESOURCE_LIST, &count);
    46 
    47         hw_resources->count = count;
    48         if (rc != EOK)
     48       
     49        if (rc != EOK) {
     50                async_exchange_end(exch);
    4951                return rc;
     52        }
    5053       
    5154        size_t size = count * sizeof(hw_resource_t);
    52         hw_resources->resources = (hw_resource_t *)malloc(size);
    53         if (!hw_resources->resources)
     55        hw_resource_t *resources = (hw_resource_t *) malloc(size);
     56        if (resources == NULL) {
     57                // FIXME: This is protocol violation
     58                async_exchange_end(exch);
    5459                return ENOMEM;
     60        }
    5561       
    56         rc = async_data_read_start(dev_phone, hw_resources->resources, size);
     62        rc = async_data_read_start(exch, resources, size);
     63        async_exchange_end(exch);
     64       
    5765        if (rc != EOK) {
    58                 free(hw_resources->resources);
    59                 hw_resources->resources = NULL;
     66                free(resources);
    6067                return rc;
    6168        }
     69       
     70        hw_resources->resources = resources;
     71        hw_resources->count = count;
    6272       
    6373        return EOK;
    6474}
    6575
    66 bool hw_res_enable_interrupt(int dev_phone)
     76bool hw_res_enable_interrupt(async_sess_t *sess)
    6777{
    68         int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
     78        async_exch_t *exch = async_exchange_begin(sess);
     79        int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
    6980            HW_RES_ENABLE_INTERRUPT);
    70 
    71         return rc == EOK;
     81        async_exchange_end(exch);
     82       
     83        return (rc == EOK);
    7284}
    7385
  • uspace/lib/c/generic/devman.c

    r52a79081 ra33f0a6  
    3535 */
    3636
     37#include <adt/list.h>
    3738#include <str.h>
    38 #include <stdio.h>
    3939#include <ipc/services.h>
     40#include <ns.h>
    4041#include <ipc/devman.h>
    4142#include <devman.h>
     43#include <fibril_synch.h>
    4244#include <async.h>
    43 #include <fibril_synch.h>
    4445#include <errno.h>
    4546#include <malloc.h>
    4647#include <bool.h>
    47 #include <adt/list.h>
    48 
    49 static int devman_phone_driver = -1;
    50 static int devman_phone_client = -1;
    51 
    52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
    53 
    54 int devman_get_phone(devman_interface_t iface, unsigned int flags)
     48
     49static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
     50static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex);
     51
     52static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex);
     53static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex);
     54
     55static async_sess_t *devman_driver_block_sess = NULL;
     56static async_sess_t *devman_client_block_sess = NULL;
     57
     58static async_sess_t *devman_driver_sess = NULL;
     59static async_sess_t *devman_client_sess = NULL;
     60
     61static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
     62    async_sess_t **dst)
     63{
     64        fibril_mutex_lock(mtx);
     65       
     66        if ((*dst == NULL) && (src != NULL))
     67                *dst = src;
     68       
     69        fibril_mutex_unlock(mtx);
     70}
     71
     72/** Start an async exchange on the devman session (blocking).
     73 *
     74 * @param iface Device manager interface to choose
     75 *
     76 * @return New exchange.
     77 *
     78 */
     79async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface)
    5580{
    5681        switch (iface) {
    5782        case DEVMAN_DRIVER:
    58                 fibril_mutex_lock(&devman_phone_mutex);
    59                 if (devman_phone_driver >= 0) {
    60                         fibril_mutex_unlock(&devman_phone_mutex);
    61                         return devman_phone_driver;
     83                fibril_mutex_lock(&devman_driver_block_mutex);
     84               
     85                while (devman_driver_block_sess == NULL) {
     86                        clone_session(&devman_driver_mutex, devman_driver_sess,
     87                            &devman_driver_block_sess);
     88                       
     89                        if (devman_driver_block_sess == NULL)
     90                                devman_driver_block_sess =
     91                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     92                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    6293                }
    6394               
    64                 if (flags & IPC_FLAG_BLOCKING)
    65                         devman_phone_driver = async_connect_me_to_blocking(
    66                             PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    67                 else
    68                         devman_phone_driver = async_connect_me_to(PHONE_NS,
    69                             SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    70                
    71                 fibril_mutex_unlock(&devman_phone_mutex);
    72                 return devman_phone_driver;
     95                fibril_mutex_unlock(&devman_driver_block_mutex);
     96               
     97                clone_session(&devman_driver_mutex, devman_driver_block_sess,
     98                    &devman_driver_sess);
     99               
     100                return async_exchange_begin(devman_driver_block_sess);
    73101        case DEVMAN_CLIENT:
    74                 fibril_mutex_lock(&devman_phone_mutex);
    75                 if (devman_phone_client >= 0) {
    76                         fibril_mutex_unlock(&devman_phone_mutex);
    77                         return devman_phone_client;
     102                fibril_mutex_lock(&devman_client_block_mutex);
     103               
     104                while (devman_client_block_sess == NULL) {
     105                        clone_session(&devman_client_mutex, devman_client_sess,
     106                            &devman_client_block_sess);
     107                       
     108                        if (devman_client_block_sess == NULL)
     109                                devman_client_block_sess =
     110                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     111                                    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    78112                }
    79113               
    80                 if (flags & IPC_FLAG_BLOCKING) {
    81                         devman_phone_client = async_connect_me_to_blocking(
    82                             PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    83                 } else {
    84                         devman_phone_client = async_connect_me_to(PHONE_NS,
    85                             SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    86                 }
    87                
    88                 fibril_mutex_unlock(&devman_phone_mutex);
    89                 return devman_phone_client;
     114                fibril_mutex_unlock(&devman_client_block_mutex);
     115               
     116                clone_session(&devman_client_mutex, devman_client_block_sess,
     117                    &devman_client_sess);
     118               
     119                return async_exchange_begin(devman_client_block_sess);
    90120        default:
    91                 return -1;
    92         }
     121                return NULL;
     122        }
     123}
     124
     125/** Start an async exchange on the devman session.
     126 *
     127 * @param iface Device manager interface to choose
     128 *
     129 * @return New exchange.
     130 *
     131 */
     132async_exch_t *devman_exchange_begin(devman_interface_t iface)
     133{
     134        switch (iface) {
     135        case DEVMAN_DRIVER:
     136                fibril_mutex_lock(&devman_driver_mutex);
     137               
     138                if (devman_driver_sess == NULL)
     139                        devman_driver_sess =
     140                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     141                            DEVMAN_DRIVER, 0);
     142               
     143                fibril_mutex_unlock(&devman_driver_mutex);
     144               
     145                if (devman_driver_sess == NULL)
     146                        return NULL;
     147               
     148                return async_exchange_begin(devman_driver_sess);
     149        case DEVMAN_CLIENT:
     150                fibril_mutex_lock(&devman_client_mutex);
     151               
     152                if (devman_client_sess == NULL)
     153                        devman_client_sess =
     154                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     155                            DEVMAN_CLIENT, 0);
     156               
     157                fibril_mutex_unlock(&devman_client_mutex);
     158               
     159                if (devman_client_sess == NULL)
     160                        return NULL;
     161               
     162                return async_exchange_begin(devman_client_sess);
     163        default:
     164                return NULL;
     165        }
     166}
     167
     168/** Finish an async exchange on the devman session.
     169 *
     170 * @param exch Exchange to be finished.
     171 *
     172 */
     173void devman_exchange_end(async_exch_t *exch)
     174{
     175        async_exchange_end(exch);
    93176}
    94177
     
    96179int devman_driver_register(const char *name, async_client_conn_t conn)
    97180{
    98         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    99        
    100         if (phone < 0)
    101                 return phone;
    102        
    103         async_serialize_start();
    104        
    105         ipc_call_t answer;
    106         aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
    107        
    108         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
    109         if (retval != EOK) {
    110                 async_wait_for(req, NULL);
    111                 async_serialize_end();
    112                 return -1;
     181        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     182       
     183        ipc_call_t answer;
     184        aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
     185        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     186       
     187        devman_exchange_end(exch);
     188       
     189        if (retval != EOK) {
     190                async_wait_for(req, NULL);
     191                return retval;
    113192        }
    114193       
    115194        async_set_client_connection(conn);
    116195       
    117         async_connect_to_me(phone, 0, 0, 0, NULL);
     196        exch = devman_exchange_begin(DEVMAN_DRIVER);
     197        async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
     198        devman_exchange_end(exch);
     199       
    118200        async_wait_for(req, &retval);
    119        
    120         async_serialize_end();
    121        
    122201        return retval;
    123 }
    124 
    125 static int devman_send_match_id(int phone, match_id_t *match_id)
    126 {
    127         ipc_call_t answer;
    128 
    129         aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
    130             &answer);
    131         int retval = async_data_write_start(phone, match_id->id,
    132             str_size(match_id->id));
    133 
    134         async_wait_for(req, NULL);
    135         return retval;
    136 }
    137 
    138 
    139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
    140 {
    141         link_t *link = match_ids->ids.next;
    142         match_id_t *match_id = NULL;
    143         int ret = EOK;
    144 
    145         while (link != &match_ids->ids) {
    146                 match_id = list_get_instance(link, match_id_t, link);
    147                 ret = devman_send_match_id(phone, match_id);
    148                 if (ret != EOK) {
    149                         return ret;
    150                 }
    151 
    152                 link = link->next;
    153         }
    154 
    155         return ret;
    156202}
    157203
     
    161207 * this driver task.
    162208 *
    163  * @param name          Name of the new function
    164  * @param ftype         Function type, fun_inner or fun_exposed
    165  * @param match_ids     Match IDs (should be empty for fun_exposed)
    166  * @param devh          Devman handle of the device
    167  * @param funh          Place to store handle of the new function
    168  *
    169  * @return              EOK on success or negative error code.
     209 * @param name      Name of the new function
     210 * @param ftype     Function type, fun_inner or fun_exposed
     211 * @param match_ids Match IDs (should be empty for fun_exposed)
     212 * @param devh      Devman handle of the device
     213 * @param funh      Place to store handle of the new function
     214 *
     215 * @return EOK on success or negative error code.
     216 *
    170217 */
    171218int devman_add_function(const char *name, fun_type_t ftype,
    172219    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
    173220{
    174         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    175         int fun_handle;
    176        
    177         if (phone < 0)
    178                 return phone;
    179        
    180         async_serialize_start();
    181        
    182221        int match_count = list_count(&match_ids->ids);
    183         ipc_call_t answer;
    184 
    185         aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     222        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     223       
     224        ipc_call_t answer;
     225        aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
    186226            devh, match_count, &answer);
    187 
    188         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
    189         if (retval != EOK) {
    190                 async_wait_for(req, NULL);
    191                 async_serialize_end();
    192                 return retval;
    193         }
    194        
    195         int match_ids_rc = devman_send_match_ids(phone, match_ids);
     227        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     228        if (retval != EOK) {
     229                devman_exchange_end(exch);
     230                async_wait_for(req, NULL);
     231                return retval;
     232        }
     233       
     234        match_id_t *match_id = NULL;
     235       
     236        list_foreach(match_ids->ids, link) {
     237                match_id = list_get_instance(link, match_id_t, link);
     238               
     239                ipc_call_t answer2;
     240                aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
     241                    match_id->score, &answer2);
     242                retval = async_data_write_start(exch, match_id->id,
     243                    str_size(match_id->id));
     244                if (retval != EOK) {
     245                        devman_exchange_end(exch);
     246                        async_wait_for(req2, NULL);
     247                        async_wait_for(req, NULL);
     248                        return retval;
     249                }
     250               
     251                async_wait_for(req2, &retval);
     252                if (retval != EOK) {
     253                        devman_exchange_end(exch);
     254                        async_wait_for(req, NULL);
     255                        return retval;
     256                }
     257        }
     258       
     259        devman_exchange_end(exch);
    196260       
    197261        async_wait_for(req, &retval);
    198        
    199         async_serialize_end();
    200        
    201         /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
    202         if ((match_ids_rc != EOK) && (retval == EOK)) {
    203                 retval = match_ids_rc;
    204         }
    205 
    206         if (retval == EOK)
    207                 fun_handle = (int) IPC_GET_ARG1(answer);
    208         else
    209                 fun_handle = -1;
    210        
    211         *funh = fun_handle;
    212 
     262        if (retval == EOK) {
     263                if (funh != NULL)
     264                        *funh = (int) IPC_GET_ARG1(answer);
     265        } else {
     266                if (funh != NULL)
     267                        *funh = -1;
     268        }
     269       
    213270        return retval;
    214271}
     
    217274    const char *class_name)
    218275{
    219         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    220        
    221         if (phone < 0)
    222                 return phone;
    223        
    224         async_serialize_start();
    225         ipc_call_t answer;
    226         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
     276        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     277       
     278        ipc_call_t answer;
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    227280            devman_handle, &answer);
    228        
    229         sysarg_t retval = async_data_write_start(phone, class_name,
     281        sysarg_t retval = async_data_write_start(exch, class_name,
    230282            str_size(class_name));
    231         if (retval != EOK) {
    232                 async_wait_for(req, NULL);
    233                 async_serialize_end();
     283       
     284        devman_exchange_end(exch);
     285       
     286        if (retval != EOK) {
     287                async_wait_for(req, NULL);
    234288                return retval;
    235289        }
    236290       
    237291        async_wait_for(req, &retval);
    238         async_serialize_end();
    239        
    240292        return retval;
    241293}
    242294
    243 void devman_hangup_phone(devman_interface_t iface)
    244 {
    245         switch (iface) {
    246         case DEVMAN_DRIVER:
    247                 if (devman_phone_driver >= 0) {
    248                         async_hangup(devman_phone_driver);
    249                         devman_phone_driver = -1;
    250                 }
    251                 break;
    252         case DEVMAN_CLIENT:
    253                 if (devman_phone_client >= 0) {
    254                         async_hangup(devman_phone_client);
    255                         devman_phone_client = -1;
    256                 }
    257                 break;
    258         default:
    259                 break;
    260         }
    261 }
    262 
    263 int devman_device_connect(devman_handle_t handle, unsigned int flags)
    264 {
    265         int phone;
    266        
    267         if (flags & IPC_FLAG_BLOCKING) {
    268                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    269                     DEVMAN_CONNECT_TO_DEVICE, handle);
    270         } else {
    271                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    272                     DEVMAN_CONNECT_TO_DEVICE, handle);
    273         }
    274        
    275         return phone;
    276 }
    277 
    278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)
    279 {
    280         int phone;
    281        
    282         if (flags & IPC_FLAG_BLOCKING) {
    283                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    284                     DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    285         } else {
    286                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    287                     DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    288         }
    289        
    290         return phone;
     295async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle,
     296    unsigned int flags)
     297{
     298        async_sess_t *sess;
     299       
     300        if (flags & IPC_FLAG_BLOCKING)
     301                sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
     302                            DEVMAN_CONNECT_TO_DEVICE, handle);
     303        else
     304                sess = service_connect(mgmt, SERVICE_DEVMAN,
     305                            DEVMAN_CONNECT_TO_DEVICE, handle);
     306       
     307        return sess;
     308}
     309
     310async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
     311    devman_handle_t handle, unsigned int flags)
     312{
     313        async_sess_t *sess;
     314       
     315        if (flags & IPC_FLAG_BLOCKING)
     316                sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
     317                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     318        else
     319                sess = service_connect(mgmt, SERVICE_DEVMAN,
     320                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     321       
     322        return sess;
    291323}
    292324
     
    294326    unsigned int flags)
    295327{
    296         int phone = devman_get_phone(DEVMAN_CLIENT, flags);
    297        
    298         if (phone < 0)
    299                 return phone;
    300        
    301         async_serialize_start();
    302        
    303         ipc_call_t answer;
    304         aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
     328        async_exch_t *exch;
     329       
     330        if (flags & IPC_FLAG_BLOCKING)
     331                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     332        else {
     333                exch = devman_exchange_begin(DEVMAN_CLIENT);
     334                if (exch == NULL)
     335                        return errno;
     336        }
     337       
     338        ipc_call_t answer;
     339        aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
    305340            &answer);
    306        
    307         sysarg_t retval = async_data_write_start(phone, pathname,
     341        sysarg_t retval = async_data_write_start(exch, pathname,
    308342            str_size(pathname));
    309         if (retval != EOK) {
    310                 async_wait_for(req, NULL);
    311                 async_serialize_end();
     343       
     344        devman_exchange_end(exch);
     345       
     346        if (retval != EOK) {
     347                async_wait_for(req, NULL);
    312348                return retval;
    313349        }
    314350       
    315351        async_wait_for(req, &retval);
    316        
    317         async_serialize_end();
    318352       
    319353        if (retval != EOK) {
    320354                if (handle != NULL)
    321355                        *handle = (devman_handle_t) -1;
     356               
    322357                return retval;
    323358        }
     
    332367    const char *devname, devman_handle_t *handle, unsigned int flags)
    333368{
    334         int phone = devman_get_phone(DEVMAN_CLIENT, flags);
    335 
    336         if (phone < 0)
    337                 return phone;
    338 
    339         async_serialize_start();
    340 
    341         ipc_call_t answer;
    342         aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     369        async_exch_t *exch;
     370       
     371        if (flags & IPC_FLAG_BLOCKING)
     372                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     373        else {
     374                exch = devman_exchange_begin(DEVMAN_CLIENT);
     375                if (exch == NULL)
     376                        return errno;
     377        }
     378       
     379        ipc_call_t answer;
     380        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
    343381            flags, &answer);
    344 
    345         sysarg_t retval = async_data_write_start(phone, classname,
     382        sysarg_t retval = async_data_write_start(exch, classname,
    346383            str_size(classname));
    347         if (retval != EOK) {
    348                 async_wait_for(req, NULL);
    349                 async_serialize_end();
    350                 return retval;
    351         }
    352         retval = async_data_write_start(phone, devname,
     384       
     385        if (retval != EOK) {
     386                devman_exchange_end(exch);
     387                async_wait_for(req, NULL);
     388                return retval;
     389        }
     390       
     391        retval = async_data_write_start(exch, devname,
    353392            str_size(devname));
    354         if (retval != EOK) {
    355                 async_wait_for(req, NULL);
    356                 async_serialize_end();
    357                 return retval;
    358         }
    359 
     393       
     394        devman_exchange_end(exch);
     395       
     396        if (retval != EOK) {
     397                async_wait_for(req, NULL);
     398                return retval;
     399        }
     400       
    360401        async_wait_for(req, &retval);
    361 
    362         async_serialize_end();
    363 
     402       
    364403        if (retval != EOK) {
    365404                if (handle != NULL)
    366405                        *handle = (devman_handle_t) -1;
    367                 return retval;
    368         }
    369 
     406               
     407                return retval;
     408        }
     409       
    370410        if (handle != NULL)
    371411                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    372 
     412       
    373413        return retval;
    374414}
    375415
     416int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     417{
     418        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     419        if (exch == NULL)
     420                return errno;
     421       
     422        ipc_call_t answer;
     423        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
     424            handle, &answer);
     425       
     426        ipc_call_t data_request_call;
     427        aid_t data_request = async_data_read(exch, path, path_size,
     428            &data_request_call);
     429       
     430        devman_exchange_end(exch);
     431       
     432        if (data_request == 0) {
     433                async_wait_for(req, NULL);
     434                return ENOMEM;
     435        }
     436       
     437        sysarg_t data_request_rc;
     438        async_wait_for(data_request, &data_request_rc);
     439       
     440        sysarg_t opening_request_rc;
     441        async_wait_for(req, &opening_request_rc);
     442       
     443        if (data_request_rc != EOK) {
     444                /* Prefer the return code of the opening request. */
     445                if (opening_request_rc != EOK)
     446                        return (int) opening_request_rc;
     447                else
     448                        return (int) data_request_rc;
     449        }
     450       
     451        if (opening_request_rc != EOK)
     452                return (int) opening_request_rc;
     453       
     454        /* To be on the safe-side. */
     455        path[path_size - 1] = 0;
     456        size_t transferred_size = IPC_GET_ARG2(data_request_call);
     457        if (transferred_size >= path_size)
     458                return ELIMIT;
     459       
     460        /* Terminate the string (trailing 0 not send over IPC). */
     461        path[transferred_size] = 0;
     462        return EOK;
     463}
    376464
    377465/** @}
  • uspace/lib/c/generic/devmap.c

    r52a79081 ra33f0a6  
    3030#include <str.h>
    3131#include <ipc/services.h>
    32 #include <ipc/ns.h>
     32#include <ns.h>
    3333#include <ipc/devmap.h>
    3434#include <devmap.h>
     35#include <fibril_synch.h>
    3536#include <async.h>
    3637#include <errno.h>
     
    3839#include <bool.h>
    3940
    40 static int devmap_phone_driver = -1;
    41 static int devmap_phone_client = -1;
    42 
    43 /** Get phone to device mapper task. */
    44 int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
     41static FIBRIL_MUTEX_INITIALIZE(devmap_driver_block_mutex);
     42static FIBRIL_MUTEX_INITIALIZE(devmap_client_block_mutex);
     43
     44static FIBRIL_MUTEX_INITIALIZE(devmap_driver_mutex);
     45static FIBRIL_MUTEX_INITIALIZE(devmap_client_mutex);
     46
     47static async_sess_t *devmap_driver_block_sess = NULL;
     48static async_sess_t *devmap_client_block_sess = NULL;
     49
     50static async_sess_t *devmap_driver_sess = NULL;
     51static async_sess_t *devmap_client_sess = NULL;
     52
     53static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
     54    async_sess_t **dst)
     55{
     56        fibril_mutex_lock(mtx);
     57       
     58        if ((*dst == NULL) && (src != NULL))
     59                *dst = src;
     60       
     61        fibril_mutex_unlock(mtx);
     62}
     63
     64/** Start an async exchange on the devmap session (blocking).
     65 *
     66 * @param iface Device mapper interface to choose
     67 *
     68 * @return New exchange.
     69 *
     70 */
     71async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t iface)
    4572{
    4673        switch (iface) {
    4774        case DEVMAP_DRIVER:
    48                 if (devmap_phone_driver >= 0)
    49                         return devmap_phone_driver;
    50                
    51                 if (flags & IPC_FLAG_BLOCKING)
    52                         devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP,
    53                             DEVMAP_DRIVER, 0);
    54                 else
    55                         devmap_phone_driver = service_connect(SERVICE_DEVMAP,
    56                             DEVMAP_DRIVER, 0);
    57                
    58                 return devmap_phone_driver;
     75                fibril_mutex_lock(&devmap_driver_block_mutex);
     76               
     77                while (devmap_driver_block_sess == NULL) {
     78                        clone_session(&devmap_driver_mutex, devmap_driver_sess,
     79                            &devmap_driver_block_sess);
     80                       
     81                        if (devmap_driver_block_sess == NULL)
     82                                devmap_driver_block_sess =
     83                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     84                                    SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
     85                }
     86               
     87                fibril_mutex_unlock(&devmap_driver_block_mutex);
     88               
     89                clone_session(&devmap_driver_mutex, devmap_driver_block_sess,
     90                    &devmap_driver_sess);
     91               
     92                return async_exchange_begin(devmap_driver_block_sess);
    5993        case DEVMAP_CLIENT:
    60                 if (devmap_phone_client >= 0)
    61                         return devmap_phone_client;
    62                
    63                 if (flags & IPC_FLAG_BLOCKING)
    64                         devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP,
    65                             DEVMAP_CLIENT, 0);
    66                 else
    67                         devmap_phone_client = service_connect(SERVICE_DEVMAP,
    68                             DEVMAP_CLIENT, 0);
    69                
    70                 return devmap_phone_client;
     94                fibril_mutex_lock(&devmap_client_block_mutex);
     95               
     96                while (devmap_client_block_sess == NULL) {
     97                        clone_session(&devmap_client_mutex, devmap_client_sess,
     98                            &devmap_client_block_sess);
     99                       
     100                        if (devmap_client_block_sess == NULL)
     101                                devmap_client_block_sess =
     102                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     103                                    SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
     104                }
     105               
     106                fibril_mutex_unlock(&devmap_client_block_mutex);
     107               
     108                clone_session(&devmap_client_mutex, devmap_client_block_sess,
     109                    &devmap_client_sess);
     110               
     111                return async_exchange_begin(devmap_client_block_sess);
    71112        default:
    72                 return -1;
    73         }
    74 }
    75 
    76 void devmap_hangup_phone(devmap_interface_t iface)
     113                return NULL;
     114        }
     115}
     116
     117/** Start an async exchange on the devmap session.
     118 *
     119 * @param iface Device mapper interface to choose
     120 *
     121 * @return New exchange.
     122 *
     123 */
     124async_exch_t *devmap_exchange_begin(devmap_interface_t iface)
    77125{
    78126        switch (iface) {
    79127        case DEVMAP_DRIVER:
    80                 if (devmap_phone_driver >= 0) {
    81                         async_hangup(devmap_phone_driver);
    82                         devmap_phone_driver = -1;
    83                 }
    84                 break;
     128                fibril_mutex_lock(&devmap_driver_mutex);
     129               
     130                if (devmap_driver_sess == NULL)
     131                        devmap_driver_sess =
     132                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
     133                            DEVMAP_DRIVER, 0);
     134               
     135                fibril_mutex_unlock(&devmap_driver_mutex);
     136               
     137                if (devmap_driver_sess == NULL)
     138                        return NULL;
     139               
     140                return async_exchange_begin(devmap_driver_sess);
    85141        case DEVMAP_CLIENT:
    86                 if (devmap_phone_client >= 0) {
    87                         async_hangup(devmap_phone_client);
    88                         devmap_phone_client = -1;
    89                 }
    90                 break;
     142                fibril_mutex_lock(&devmap_client_mutex);
     143               
     144                if (devmap_client_sess == NULL)
     145                        devmap_client_sess =
     146                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
     147                            DEVMAP_CLIENT, 0);
     148               
     149                fibril_mutex_unlock(&devmap_client_mutex);
     150               
     151                if (devmap_client_sess == NULL)
     152                        return NULL;
     153               
     154                return async_exchange_begin(devmap_client_sess);
    91155        default:
    92                 break;
    93         }
     156                return NULL;
     157        }
     158}
     159
     160/** Finish an async exchange on the devmap session.
     161 *
     162 * @param exch Exchange to be finished.
     163 *
     164 */
     165void devmap_exchange_end(async_exch_t *exch)
     166{
     167        async_exchange_end(exch);
    94168}
    95169
     
    97171int devmap_driver_register(const char *name, async_client_conn_t conn)
    98172{
    99         int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
    100        
    101         if (phone < 0)
    102                 return phone;
    103        
    104         async_serialize_start();
     173        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
    105174       
    106175        ipc_call_t answer;
    107         aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
    108        
    109         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     176        aid_t req = async_send_2(exch, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
     177        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     178       
     179        devmap_exchange_end(exch);
     180       
    110181        if (retval != EOK) {
    111182                async_wait_for(req, NULL);
    112                 async_serialize_end();
    113                 return -1;
     183                return retval;
    114184        }
    115185       
    116186        async_set_client_connection(conn);
    117187       
    118         async_connect_to_me(phone, 0, 0, 0, NULL);
     188        exch = devmap_exchange_begin(DEVMAP_DRIVER);
     189        async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
     190        devmap_exchange_end(exch);
     191       
    119192        async_wait_for(req, &retval);
    120        
    121         async_serialize_end();
    122        
    123193        return retval;
    124194}
     
    129199 * If not 0, the first argument is the interface and the second argument
    130200 * is the devmap handle of the device.
     201 *
    131202 * When the interface is zero (default), the first argument is directly
    132203 * the handle (to ensure backward compatibility).
    133204 *
    134  * @param fqdn Fully qualified device name.
    135  * @param[out] handle Handle to the created instance of device.
    136  * @param interface Interface when forwarding.
     205 * @param      fqdn      Fully qualified device name.
     206 * @param[out] handle    Handle to the created instance of device.
     207 * @param      interface Interface when forwarding.
    137208 *
    138209 */
     
    140211    devmap_handle_t *handle, sysarg_t interface)
    141212{
    142         int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
    143        
    144         if (phone < 0)
    145                 return phone;
    146        
    147         async_serialize_start();
     213        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
    148214       
    149215        ipc_call_t answer;
    150         aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0,
     216        aid_t req = async_send_2(exch, DEVMAP_DEVICE_REGISTER, interface, 0,
    151217            &answer);
    152        
    153         sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
     218        sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
     219       
     220        devmap_exchange_end(exch);
     221       
    154222        if (retval != EOK) {
    155223                async_wait_for(req, NULL);
    156                 async_serialize_end();
    157224                return retval;
    158225        }
    159226       
    160227        async_wait_for(req, &retval);
    161        
    162         async_serialize_end();
    163228       
    164229        if (retval != EOK) {
    165230                if (handle != NULL)
    166231                        *handle = -1;
     232               
    167233                return retval;
    168234        }
     
    176242/** Register new device.
    177243 *
    178  * @param fqdn      Fully qualified device name.
    179  * @param handle    Output: Handle to the created instance of device.
     244 * @param fqdn   Fully qualified device name.
     245 * @param handle Output: Handle to the created instance of device.
    180246 *
    181247 */
     
    185251}
    186252
    187 
    188 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags)
    189 {
    190         int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
    191        
    192         if (phone < 0)
    193                 return phone;
    194        
    195         async_serialize_start();
     253int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle,
     254    unsigned int flags)
     255{
     256        async_exch_t *exch;
     257       
     258        if (flags & IPC_FLAG_BLOCKING)
     259                exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     260        else {
     261                exch = devmap_exchange_begin(DEVMAP_CLIENT);
     262                if (exch == NULL)
     263                        return errno;
     264        }
    196265       
    197266        ipc_call_t answer;
    198         aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
     267        aid_t req = async_send_2(exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
    199268            &answer);
    200        
    201         sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
     269        sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
     270       
     271        devmap_exchange_end(exch);
     272       
    202273        if (retval != EOK) {
    203274                async_wait_for(req, NULL);
    204                 async_serialize_end();
    205275                return retval;
    206276        }
    207277       
    208278        async_wait_for(req, &retval);
    209        
    210         async_serialize_end();
    211279       
    212280        if (retval != EOK) {
    213281                if (handle != NULL)
    214282                        *handle = (devmap_handle_t) -1;
     283               
    215284                return retval;
    216285        }
     
    222291}
    223292
    224 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags)
    225 {
    226         int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
    227        
    228         if (phone < 0)
    229                 return phone;
    230        
    231         async_serialize_start();
     293int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle,
     294    unsigned int flags)
     295{
     296        async_exch_t *exch;
     297       
     298        if (flags & IPC_FLAG_BLOCKING)
     299                exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     300        else {
     301                exch = devmap_exchange_begin(DEVMAP_CLIENT);
     302                if (exch == NULL)
     303                        return errno;
     304        }
    232305       
    233306        ipc_call_t answer;
    234         aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
     307        aid_t req = async_send_2(exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
    235308            &answer);
    236        
    237         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     309        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     310       
     311        devmap_exchange_end(exch);
     312       
    238313        if (retval != EOK) {
    239314                async_wait_for(req, NULL);
    240                 async_serialize_end();
    241315                return retval;
    242316        }
    243317       
    244318        async_wait_for(req, &retval);
    245        
    246         async_serialize_end();
    247319       
    248320        if (retval != EOK) {
    249321                if (handle != NULL)
    250322                        *handle = (devmap_handle_t) -1;
     323               
    251324                return retval;
    252325        }
     
    260333devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle)
    261334{
    262         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    263        
    264         if (phone < 0)
    265                 return phone;
     335        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
    266336       
    267337        sysarg_t type;
    268         int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
     338        int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type);
     339       
     340        devmap_exchange_end(exch);
     341       
    269342        if (retval != EOK)
    270343                return DEV_HANDLE_NONE;
     
    273346}
    274347
    275 int devmap_device_connect(devmap_handle_t handle, unsigned int flags)
    276 {
    277         int phone;
    278        
    279         if (flags & IPC_FLAG_BLOCKING) {
    280                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
     348async_sess_t *devmap_device_connect(exch_mgmt_t mgmt, devmap_handle_t handle,
     349    unsigned int flags)
     350{
     351        async_sess_t *sess;
     352       
     353        if (flags & IPC_FLAG_BLOCKING)
     354                sess = service_connect_blocking(mgmt, SERVICE_DEVMAP,
    281355                    DEVMAP_CONNECT_TO_DEVICE, handle);
    282         } else {
    283                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
     356        else
     357                sess = service_connect(mgmt, SERVICE_DEVMAP,
    284358                    DEVMAP_CONNECT_TO_DEVICE, handle);
    285         }
    286        
    287         return phone;
     359       
     360        return sess;
    288361}
    289362
    290363int devmap_null_create(void)
    291364{
    292         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    293        
    294         if (phone < 0)
    295                 return -1;
     365        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
    296366       
    297367        sysarg_t null_id;
    298         int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
     368        int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id);
     369       
     370        devmap_exchange_end(exch);
     371       
    299372        if (retval != EOK)
    300373                return -1;
     
    305378void devmap_null_destroy(int null_id)
    306379{
    307         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    308        
    309         if (phone < 0)
    310                 return;
    311        
    312         async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
    313 }
    314 
    315 static size_t devmap_count_namespaces_internal(int phone)
     380        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     381        async_req_1_0(exch, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
     382        devmap_exchange_end(exch);
     383}
     384
     385static size_t devmap_count_namespaces_internal(async_exch_t *exch)
    316386{
    317387        sysarg_t count;
    318         int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
     388        int retval = async_req_0_1(exch, DEVMAP_GET_NAMESPACE_COUNT, &count);
    319389        if (retval != EOK)
    320390                return 0;
     
    323393}
    324394
    325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle)
     395static size_t devmap_count_devices_internal(async_exch_t *exch,
     396    devmap_handle_t ns_handle)
    326397{
    327398        sysarg_t count;
    328         int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
     399        int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle,
     400            &count);
    329401        if (retval != EOK)
    330402                return 0;
     
    335407size_t devmap_count_namespaces(void)
    336408{
    337         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    338        
    339         if (phone < 0)
    340                 return 0;
    341        
    342         return devmap_count_namespaces_internal(phone);
     409        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     410        size_t size = devmap_count_namespaces_internal(exch);
     411        devmap_exchange_end(exch);
     412       
     413        return size;
    343414}
    344415
    345416size_t devmap_count_devices(devmap_handle_t ns_handle)
    346417{
    347         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    348        
    349         if (phone < 0)
    350                 return 0;
    351        
    352         return devmap_count_devices_internal(phone, ns_handle);
     418        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     419        size_t size = devmap_count_devices_internal(exch, ns_handle);
     420        devmap_exchange_end(exch);
     421       
     422        return size;
    353423}
    354424
    355425size_t devmap_get_namespaces(dev_desc_t **data)
    356426{
    357         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    358        
    359         if (phone < 0)
    360                 return 0;
    361        
    362427        /* Loop until namespaces read succesful */
    363428        while (true) {
    364                 size_t count = devmap_count_namespaces_internal(phone);
     429                async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     430                size_t count = devmap_count_namespaces_internal(exch);
     431                devmap_exchange_end(exch);
     432               
    365433                if (count == 0)
    366434                        return 0;
     
    370438                        return 0;
    371439               
    372                 async_serialize_start();
     440                exch = devmap_exchange_begin(DEVMAP_CLIENT);
    373441               
    374442                ipc_call_t answer;
    375                 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
    376                
    377                 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     443                aid_t req = async_send_0(exch, DEVMAP_GET_NAMESPACES, &answer);
     444                int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
     445               
     446                devmap_exchange_end(exch);
     447               
    378448                if (rc == EOVERFLOW) {
    379449                        /*
     
    381451                         * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
    382452                         */
    383                         async_serialize_end();
    384453                        free(devs);
    385454                        continue;
     
    388457                if (rc != EOK) {
    389458                        async_wait_for(req, NULL);
    390                         async_serialize_end();
    391459                        free(devs);
    392460                        return 0;
     
    395463                sysarg_t retval;
    396464                async_wait_for(req, &retval);
    397                 async_serialize_end();
    398465               
    399466                if (retval != EOK)
     
    407474size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data)
    408475{
    409         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    410        
    411         if (phone < 0)
    412                 return 0;
    413        
    414         /* Loop until namespaces read succesful */
     476        /* Loop until devices read succesful */
    415477        while (true) {
    416                 size_t count = devmap_count_devices_internal(phone, ns_handle);
     478                async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     479                size_t count = devmap_count_devices_internal(exch, ns_handle);
     480                devmap_exchange_end(exch);
     481               
    417482                if (count == 0)
    418483                        return 0;
     
    422487                        return 0;
    423488               
    424                 async_serialize_start();
     489                exch = devmap_exchange_begin(DEVMAP_CLIENT);
    425490               
    426491                ipc_call_t answer;
    427                 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
    428                
    429                 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     492                aid_t req = async_send_1(exch, DEVMAP_GET_DEVICES, ns_handle, &answer);
     493                int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
     494               
     495                devmap_exchange_end(exch);
     496               
    430497                if (rc == EOVERFLOW) {
    431498                        /*
     
    433500                         * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
    434501                         */
    435                         async_serialize_end();
    436502                        free(devs);
    437503                        continue;
     
    440506                if (rc != EOK) {
    441507                        async_wait_for(req, NULL);
    442                         async_serialize_end();
    443508                        free(devs);
    444509                        return 0;
     
    447512                sysarg_t retval;
    448513                async_wait_for(req, &retval);
    449                 async_serialize_end();
    450514               
    451515                if (retval != EOK)
  • uspace/lib/c/generic/elf/elf_load.c

    r52a79081 ra33f0a6  
    22 * Copyright (c) 2006 Sergey Bondari
    33 * Copyright (c) 2006 Jakub Jermar
    4  * Copyright (c) 2008 Jiri Svoboda
     4 * Copyright (c) 2011 Jiri Svoboda
    55 * All rights reserved.
    66 *
     
    2929 */
    3030
    31 /** @addtogroup generic 
     31/** @addtogroup generic
    3232 * @{
    3333 */
     
    4949#include <assert.h>
    5050#include <as.h>
     51#include <elf/elf.h>
    5152#include <unistd.h>
    5253#include <fcntl.h>
    5354#include <smc.h>
    5455#include <loader/pcb.h>
    55 
    56 #include "elf.h"
    57 #include "elf_load.h"
    58 #include "arch.h"
     56#include <entry_point.h>
     57
     58#include <elf/elf_load.h>
    5959
    6060#define DPRINTF(...)
     
    7474static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7575
    76 /** Read until the buffer is read in its entirety. */
    77 static int my_read(int fd, void *buf, size_t len)
    78 {
    79         int cnt = 0;
    80         do {
    81                 buf += cnt;
    82                 len -= cnt;
    83                 cnt = read(fd, buf, len);
    84         } while ((cnt > 0) && ((len - cnt) > 0));
    85 
    86         return cnt;
    87 }
    88 
    8976/** Load ELF binary from a file.
    9077 *
     
    10390 *
    10491 */
    105 int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info)
     92int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
     93    elf_info_t *info)
    10694{
    10795        elf_ld_t elf;
     
    118106        elf.fd = fd;
    119107        elf.info = info;
     108        elf.flags = flags;
    120109
    121110        rc = elf_load(&elf, so_bias);
     
    124113
    125114        return rc;
    126 }
    127 
    128 /** Run an ELF executable.
    129  *
    130  * Transfers control to the entry point of an ELF executable loaded
    131  * earlier with elf_load_file(). This function does not return.
    132  *
    133  * @param info Info structure filled earlier by elf_load_file()
    134  *
    135  */
    136 void elf_run(elf_info_t *info, pcb_t *pcb)
    137 {
    138         program_run(info->entry, pcb);
    139 
    140         /* not reached */
    141115}
    142116
     
    153127        pcb->entry = info->entry;
    154128        pcb->dynamic = info->dynamic;
     129        pcb->rtld_runtime = NULL;
    155130}
    156131
     
    172147        int i, rc;
    173148
    174         rc = my_read(elf->fd, header, sizeof(elf_header_t));
    175         if (rc < 0) {
     149        rc = read_all(elf->fd, header, sizeof(elf_header_t));
     150        if (rc != sizeof(elf_header_t)) {
    176151                DPRINTF("Read error.\n");
    177152                return EE_INVALID;
     
    234209                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    235210
    236                 rc = my_read(elf->fd, &segment_hdr,
     211                rc = read_all(elf->fd, &segment_hdr,
    237212                    sizeof(elf_segment_header_t));
    238                 if (rc < 0) {
     213                if (rc != sizeof(elf_segment_header_t)) {
    239214                        DPRINTF("Read error.\n");
    240215                        return EE_INVALID;
     
    256231                    + i * sizeof(elf_section_header_t), SEEK_SET);
    257232
    258                 rc = my_read(elf->fd, &section_hdr,
     233                rc = read_all(elf->fd, &section_hdr,
    259234                    sizeof(elf_section_header_t));
    260                 if (rc < 0) {
     235                if (rc != sizeof(elf_section_header_t)) {
    261236                        DPRINTF("Read error.\n");
    262237                        return EE_INVALID;
     
    306281                break;
    307282        case PT_INTERP:
    308                 /* Assume silently interp == "/rtld.so" */
    309                 elf->info->interp = "/rtld.so";
     283                /* Assume silently interp == "/app/dload" */
     284                elf->info->interp = "/app/dload";
    310285                break;
    311286        case PT_DYNAMIC:
     287                /* Record pointer to dynamic section into info structure */
     288                elf->info->dynamic =
     289                    (void *)((uint8_t *)entry->p_vaddr + elf->bias);
     290                DPRINTF("dynamic section found at 0x%x\n",
     291                        (uintptr_t)elf->info->dynamic);
     292                break;
     293        case 0x70000000:
     294                /* FIXME: MIPS reginfo */
     295                break;
    312296        case PT_SHLIB:
    313         case PT_LOPROC:
    314         case PT_HIPROC:
     297//      case PT_LOPROC:
     298//      case PT_HIPROC:
    315299        default:
    316300                DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
     
    337321        uintptr_t seg_addr;
    338322        size_t mem_sz;
    339         int rc;
     323        ssize_t rc;
    340324
    341325        bias = elf->bias;
     
    383367            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
    384368        if (a == (void *)(-1)) {
    385                 DPRINTF("Memory mapping failed.\n");
     369                DPRINTF("memory mapping failed (0x%x, %d)\n",
     370                        base+bias, mem_sz);
    386371                return EE_MEMORY;
    387372        }
     
    414399                if (now > left) now = left;
    415400
    416                 rc = my_read(elf->fd, dp, now);
    417 
    418                 if (rc < 0) {
     401                rc = read_all(elf->fd, dp, now);
     402
     403                if (rc != (ssize_t) now) {
    419404                        DPRINTF("Read error.\n");
    420405                        return EE_INVALID;
     
    425410        }
    426411
     412        /*
     413         * The caller wants to modify the segments first. He will then
     414         * need to set the right access mode and ensure SMC coherence.
     415         */
     416        if ((elf->flags & ELDF_RW) != 0) return EE_OK;
     417
     418//      printf("set area flags to %d\n", flags);
    427419        rc = as_area_change_flags(seg_ptr, flags);
    428420        if (rc != 0) {
  • uspace/lib/c/generic/event.c

    r52a79081 ra33f0a6  
    4141#include <kernel/ipc/event_types.h>
    4242
    43 /** Subscribe for event notifications.
     43/** Subscribe event notifications.
    4444 *
    45  * @param evno   Event number.
    46  * @param method Use this method for notifying me.
     45 * @param evno    Event type to subscribe.
     46 * @param imethod Use this interface and method for notifying me.
    4747 *
    4848 * @return Value returned by the kernel.
     49 *
    4950 */
    50 int event_subscribe(event_type_t e, sysarg_t method)
     51int event_subscribe(event_type_t evno, sysarg_t imethod)
    5152{
    52         return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method);
     53        return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
     54            (sysarg_t) imethod);
     55}
     56
     57/** Unmask event notifications.
     58 *
     59 * @param evno Event type to unmask.
     60 *
     61 * @return Value returned by the kernel.
     62 *
     63 */
     64int event_unmask(event_type_t evno)
     65{
     66        return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
    5367}
    5468
  • uspace/lib/c/generic/fibril.c

    r52a79081 ra33f0a6  
    222222        fibril_t *dstf;
    223223        if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
    224                 dstf = list_get_instance(manager_list.next, fibril_t, link);
     224                dstf = list_get_instance(list_first(&manager_list), fibril_t,
     225                    link);
    225226                if (serialization_count && stype == FIBRIL_TO_MANAGER) {
    226227                        serialized_threads++;
     
    233234        } else {
    234235                if (!list_empty(&serialized_list)) {
    235                         dstf = list_get_instance(serialized_list.next, fibril_t,
    236                             link);
     236                        dstf = list_get_instance(list_first(&serialized_list),
     237                            fibril_t, link);
    237238                        serialized_threads--;
    238239                } else {
    239                         dstf = list_get_instance(ready_list.next, fibril_t,
    240                             link);
     240                        dstf = list_get_instance(list_first(&ready_list),
     241                            fibril_t, link);
    241242                }
    242243        }
     
    326327       
    327328        if (!list_empty(&manager_list))
    328                 list_remove(manager_list.next);
     329                list_remove(list_first(&manager_list));
    329330       
    330331        futex_up(&fibril_futex);
  • uspace/lib/c/generic/fibril_synch.c

    r52a79081 ra33f0a6  
    148148                fibril_t *f;
    149149       
    150                 assert(!list_empty(&fm->waiters));
    151                 tmp = fm->waiters.next;
     150                tmp = list_first(&fm->waiters);
     151                assert(tmp != NULL);
    152152                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    153153                wdp->active = true;
     
    279279       
    280280        while (!list_empty(&frw->waiters)) {
    281                 link_t *tmp = frw->waiters.next;
     281                link_t *tmp = list_first(&frw->waiters);
    282282                awaiter_t *wdp;
    283283                fibril_t *f;
     
    422422        futex_down(&async_futex);
    423423        while (!list_empty(&fcv->waiters)) {
    424                 tmp = fcv->waiters.next;
     424                tmp = list_first(&fcv->waiters);
    425425                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    426426                list_remove(&wdp->wu_event.link);
  • uspace/lib/c/generic/io/console.c

    r52a79081 ra33f0a6  
    3737#include <libc.h>
    3838#include <async.h>
     39#include <errno.h>
     40#include <stdio.h>
     41#include <malloc.h>
     42#include <vfs/vfs_sess.h>
    3943#include <io/console.h>
    4044#include <ipc/console.h>
    4145
    42 void console_clear(int phone)
    43 {
    44         async_msg_0(phone, CONSOLE_CLEAR);
    45 }
    46 
    47 int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows)
    48 {
    49         return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows);
    50 }
    51 
    52 void console_set_style(int phone, uint8_t style)
    53 {
    54         async_msg_1(phone, CONSOLE_SET_STYLE, style);
    55 }
    56 
    57 void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
     46console_ctrl_t *console_init(FILE *ifile, FILE *ofile)
     47{
     48        console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t));
     49        if (!ctrl)
     50                return NULL;
     51       
     52        ctrl->input_sess = fsession(EXCHANGE_SERIALIZE, ifile);
     53        if (!ctrl->input_sess) {
     54                free(ctrl);
     55                return NULL;
     56        }
     57       
     58        ctrl->output_sess = fsession(EXCHANGE_SERIALIZE, ofile);
     59        if (!ctrl->output_sess) {
     60                free(ctrl);
     61                return NULL;
     62        }
     63       
     64        ctrl->input = ifile;
     65        ctrl->output = ofile;
     66        ctrl->input_aid = 0;
     67       
     68        return ctrl;
     69}
     70
     71void console_done(console_ctrl_t *ctrl)
     72{
     73        free(ctrl);
     74}
     75
     76bool console_kcon(void)
     77{
     78        return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
     79}
     80
     81void console_flush(console_ctrl_t *ctrl)
     82{
     83        fflush(ctrl->output);
     84}
     85
     86void console_clear(console_ctrl_t *ctrl)
     87{
     88        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     89        async_msg_0(exch, CONSOLE_CLEAR);
     90        async_exchange_end(exch);
     91}
     92
     93int console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows)
     94{
     95        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     96        int rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows);
     97        async_exchange_end(exch);
     98       
     99        return rc;
     100}
     101
     102void console_set_style(console_ctrl_t *ctrl, uint8_t style)
     103{
     104        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     105        async_msg_1(exch, CONSOLE_SET_STYLE, style);
     106        async_exchange_end(exch);
     107}
     108
     109void console_set_color(console_ctrl_t *ctrl, uint8_t fg_color, uint8_t bg_color,
    58110    uint8_t flags)
    59111{
    60         async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
    61 }
    62 
    63 void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color)
    64 {
    65         async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
    66 }
    67 
    68 void console_cursor_visibility(int phone, bool show)
    69 {
    70         async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false));
    71 }
    72 
    73 int console_get_color_cap(int phone, sysarg_t *ccap)
    74 {
    75         return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap);
    76 }
    77 
    78 void console_kcon_enable(int phone)
    79 {
    80         async_msg_0(phone, CONSOLE_KCON_ENABLE);
    81 }
    82 
    83 int console_get_pos(int phone, sysarg_t *col, sysarg_t *row)
    84 {
    85         return async_req_0_2(phone, CONSOLE_GET_POS, col, row);
    86 }
    87 
    88 void console_set_pos(int phone, sysarg_t col, sysarg_t row)
    89 {
    90         async_msg_2(phone, CONSOLE_GOTO, col, row);
    91 }
    92 
    93 bool console_get_event(int phone, console_event_t *event)
    94 {
    95         sysarg_t type;
    96         sysarg_t key;
    97         sysarg_t mods;
    98         sysarg_t c;
    99        
    100         int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
    101         if (rc < 0)
     112        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     113        async_msg_3(exch, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
     114        async_exchange_end(exch);
     115}
     116
     117void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t fg_color,
     118    uint32_t bg_color)
     119{
     120        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     121        async_msg_2(exch, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
     122        async_exchange_end(exch);
     123}
     124
     125void console_cursor_visibility(console_ctrl_t *ctrl, bool show)
     126{
     127        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     128        async_msg_1(exch, CONSOLE_CURSOR_VISIBILITY, (show != false));
     129        async_exchange_end(exch);
     130}
     131
     132int console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap)
     133{
     134        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     135        int rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap);
     136        async_exchange_end(exch);
     137       
     138        return rc;
     139}
     140
     141int console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row)
     142{
     143        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     144        int rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row);
     145        async_exchange_end(exch);
     146       
     147        return rc;
     148}
     149
     150void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row)
     151{
     152        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     153        async_msg_2(exch, CONSOLE_GOTO, col, row);
     154        async_exchange_end(exch);
     155}
     156
     157bool console_get_kbd_event(console_ctrl_t *ctrl, kbd_event_t *event)
     158{
     159        if (ctrl->input_aid == 0) {
     160                sysarg_t type;
     161                sysarg_t key;
     162                sysarg_t mods;
     163                sysarg_t c;
     164               
     165                async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
     166                int rc = async_req_0_4(exch, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
     167                async_exchange_end(exch);
     168               
     169                if (rc != EOK) {
     170                        errno = rc;
     171                        return false;
     172                }
     173               
     174                event->type = type;
     175                event->key = key;
     176                event->mods = mods;
     177                event->c = c;
     178        } else {
     179                sysarg_t retval;
     180                async_wait_for(ctrl->input_aid, &retval);
     181               
     182                ctrl->input_aid = 0;
     183               
     184                if (retval != EOK) {
     185                        errno = (int) retval;
     186                        return false;
     187                }
     188               
     189                event->type = IPC_GET_ARG1(ctrl->input_call);
     190                event->key = IPC_GET_ARG2(ctrl->input_call);
     191                event->mods = IPC_GET_ARG3(ctrl->input_call);
     192                event->c = IPC_GET_ARG4(ctrl->input_call);
     193        }
     194       
     195        return true;
     196}
     197
     198bool console_get_kbd_event_timeout(console_ctrl_t *ctrl, kbd_event_t *event,
     199    suseconds_t *timeout)
     200{
     201        struct timeval t0;
     202        gettimeofday(&t0, NULL);
     203       
     204        if (ctrl->input_aid == 0) {
     205                async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
     206                ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT,
     207                    &ctrl->input_call);
     208                async_exchange_end(exch);
     209        }
     210       
     211        sysarg_t retval;
     212        int rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
     213        if (rc != EOK) {
     214                *timeout = 0;
     215                errno = rc;
    102216                return false;
    103        
    104         event->type = type;
    105         event->key = key;
    106         event->mods = mods;
    107         event->c = c;
     217        }
     218       
     219        ctrl->input_aid = 0;
     220       
     221        if (retval != EOK) {
     222                errno = (int) retval;
     223                return false;
     224        }
     225       
     226        event->type = IPC_GET_ARG1(ctrl->input_call);
     227        event->key = IPC_GET_ARG2(ctrl->input_call);
     228        event->mods = IPC_GET_ARG3(ctrl->input_call);
     229        event->c = IPC_GET_ARG4(ctrl->input_call);
     230       
     231        /* Update timeout */
     232        struct timeval t1;
     233        gettimeofday(&t1, NULL);
     234        *timeout -= tv_sub(&t1, &t0);
    108235       
    109236        return true;
  • uspace/lib/c/generic/io/io.c

    r52a79081 ra33f0a6  
    4444#include <io/klog.h>
    4545#include <vfs/vfs.h>
     46#include <vfs/vfs_sess.h>
    4647#include <ipc/devmap.h>
    4748#include <adt/list.h>
    4849#include "../private/io.h"
     50#include "../private/stdio.h"
    4951
    5052static void _ffillbuf(FILE *stream);
     
    5658        .eof = true,
    5759        .klog = false,
    58         .phone = -1,
     60        .sess = NULL,
    5961        .btype = _IONBF,
    6062        .buf = NULL,
     
    7072        .eof = false,
    7173        .klog = true,
    72         .phone = -1,
     74        .sess = NULL,
    7375        .btype = _IOLBF,
    7476        .buf = NULL,
     
    8486        .eof = false,
    8587        .klog = true,
    86         .phone = -1,
     88        .sess = NULL,
    8789        .btype = _IONBF,
    8890        .buf = NULL,
     
    125127void __stdio_done(void)
    126128{
    127         link_t *link = files.next;
    128        
    129         while (link != &files) {
    130                 FILE *file = list_get_instance(link, FILE, link);
     129        while (!list_empty(&files)) {
     130                FILE *file = list_get_instance(list_first(&files), FILE, link);
    131131                fclose(file);
    132                 link = files.next;
    133132        }
    134133}
     
    255254        stream->eof = false;
    256255        stream->klog = false;
    257         stream->phone = -1;
     256        stream->sess = NULL;
    258257        stream->need_sync = false;
    259258        _setvbuf(stream);
     
    277276        stream->eof = false;
    278277        stream->klog = false;
    279         stream->phone = -1;
     278        stream->sess = NULL;
    280279        stream->need_sync = false;
    281280        _setvbuf(stream);
     
    309308        stream->eof = false;
    310309        stream->klog = false;
    311         stream->phone = -1;
     310        stream->sess = NULL;
    312311        stream->need_sync = false;
    313312        _setvbuf(stream);
     
    324323        fflush(stream);
    325324       
    326         if (stream->phone >= 0)
    327                 async_hangup(stream->phone);
     325        if (stream->sess != NULL)
     326                async_hangup(stream->sess);
    328327       
    329328        if (stream->fd >= 0)
     
    595594                }
    596595               
    597                 buf += now;
     596                data += now;
    598597                stream->buf_head += now;
    599598                buf_free -= now;
    600599                bytes_left -= now;
    601600                total_written += now;
     601                stream->buf_state = _bs_write;
    602602               
    603603                if (buf_free == 0) {
     
    607607                }
    608608        }
    609        
    610         if (total_written > 0)
    611                 stream->buf_state = _bs_write;
    612609
    613610        if (need_flush)
     
    715712off64_t ftell(FILE *stream)
    716713{
     714        _fflushbuf(stream);
    717715        return lseek(stream->fd, 0, SEEK_CUR);
    718716}
     
    732730        }
    733731       
    734         if (stream->fd >= 0 && stream->need_sync) {
     732        if ((stream->fd >= 0) && (stream->need_sync)) {
    735733                /**
    736734                 * Better than syncing always, but probably still not the
     
    770768}
    771769
    772 int fphone(FILE *stream)
     770async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
    773771{
    774772        if (stream->fd >= 0) {
    775                 if (stream->phone < 0)
    776                         stream->phone = fd_phone(stream->fd);
    777                
    778                 return stream->phone;
    779         }
    780        
    781         return -1;
     773                if (stream->sess == NULL)
     774                        stream->sess = fd_session(mgmt, stream->fd);
     775               
     776                return stream->sess;
     777        }
     778       
     779        return NULL;
    782780}
    783781
  • uspace/lib/c/generic/io/klog.c

    r52a79081 ra33f0a6  
    3838#include <sys/types.h>
    3939#include <unistd.h>
     40#include <errno.h>
    4041#include <io/klog.h>
     42#include <io/printf_core.h>
    4143
    4244size_t klog_write(const void *buf, size_t size)
     
    5557}
    5658
     59/** Print formatted text to klog.
     60 *
     61 * @param fmt Format string
     62 *
     63 * \see For more details about format string see printf_core.
     64 *
     65 */
     66int klog_printf(const char *fmt, ...)
     67{
     68        va_list args;
     69        va_start(args, fmt);
     70       
     71        int ret = klog_vprintf(fmt, args);
     72       
     73        va_end(args);
     74       
     75        return ret;
     76}
     77
     78static int klog_vprintf_str_write(const char *str, size_t size, void *data)
     79{
     80        size_t wr = klog_write(str, size);
     81        return str_nlength(str, wr);
     82}
     83
     84static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
     85{
     86        size_t offset = 0;
     87        size_t chars = 0;
     88       
     89        while (offset < size) {
     90                char buf[STR_BOUNDS(1)];
     91                size_t sz = 0;
     92               
     93                if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
     94                        klog_write(buf, sz);
     95               
     96                chars++;
     97                offset += sizeof(wchar_t);
     98        }
     99       
     100        return chars;
     101}
     102
     103/** Print formatted text to klog.
     104 *
     105 * @param fmt Format string
     106 * @param ap  Format parameters
     107 *
     108 * \see For more details about format string see printf_core.
     109 *
     110 */
     111int klog_vprintf(const char *fmt, va_list ap)
     112{
     113        printf_spec_t ps = {
     114                klog_vprintf_str_write,
     115                klog_vprintf_wstr_write,
     116                NULL
     117        };
     118       
     119        return printf_core(fmt, &ps, ap);
     120}
     121
    57122/** @}
    58123 */
  • uspace/lib/c/generic/io/vprintf.c

    r52a79081 ra33f0a6  
    9696/** Print formatted text to stdout.
    9797 *
    98  * @param file Output stream
    99  * @param fmt  Format string
    100  * @param ap   Format parameters
     98 * @param fmt Format string
     99 * @param ap  Format parameters
    101100 *
    102101 * \see For more details about format string see printf_core.
  • uspace/lib/c/generic/ipc.c

    r52a79081 ra33f0a6  
    458458        while (!list_empty(&queued_calls)) {
    459459                async_call_t *call =
    460                     list_get_instance(queued_calls.next, async_call_t, list);
     460                    list_get_instance(list_first(&queued_calls), async_call_t, list);
    461461                ipc_callid_t callid =
    462462                    ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data);
     
    511511       
    512512        link_t *item;
    513         for (item = dispatched_calls.next; item != &dispatched_calls;
     513        for (item = dispatched_calls.head.next; item != &dispatched_calls.head;
    514514            item = item->next) {
    515515                async_call_t *call =
     
    632632}
    633633
     634/** Request cloned connection.
     635 *
     636 * @param phoneid Phone handle used for contacting the other side.
     637 *
     638 * @return Cloned phone handle on success or a negative error code.
     639 *
     640 */
     641int ipc_connect_me(int phoneid)
     642{
     643        sysarg_t newphid;
     644        int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL,
     645            NULL, NULL, &newphid);
     646        if (res)
     647                return res;
     648       
     649        return newphid;
     650}
     651
    634652/** Request new connection.
    635653 *
  • uspace/lib/c/generic/libc.c

    r52a79081 ra33f0a6  
    4949#include "private/libc.h"
    5050#include "private/async.h"
    51 #include "private/async_sess.h"
    5251#include "private/malloc.h"
    5352#include "private/io.h"
     53
     54#ifdef CONFIG_RTLD
     55#include <rtld/rtld.h>
     56#endif
    5457
    5558static bool env_setup = false;
     
    6063        __malloc_init();
    6164        __async_init();
    62         __async_sess_init();
    6365       
    6466        fibril_t *fibril = fibril_setup();
     
    7779        char **argv;
    7880       
     81#ifdef __IN_SHARED_LIBC__
     82        if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
     83                runtime_env = (runtime_env_t *) __pcb->rtld_runtime;
     84        }
     85#endif
    7986        /*
    8087         * Get command line arguments and initialize
  • uspace/lib/c/generic/loader.c

    r52a79081 ra33f0a6  
    3535#include <ipc/loader.h>
    3636#include <ipc/services.h>
    37 #include <ipc/ns.h>
     37#include <ns.h>
    3838#include <libc.h>
    3939#include <task.h>
     
    4444#include <vfs/vfs.h>
    4545#include <loader/loader.h>
     46#include "private/loader.h"
    4647
    4748/** Connect to a new program loader.
     
    6364loader_t *loader_connect(void)
    6465{
    65         int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);
    66         if (phone_id < 0)
    67                 return NULL;
    68        
    6966        loader_t *ldr = malloc(sizeof(loader_t));
    7067        if (ldr == NULL)
    7168                return NULL;
    7269       
    73         ldr->phone_id = phone_id;
     70        async_sess_t *sess =
     71            service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOAD, 0, 0);
     72        if (sess == NULL) {
     73                free(ldr);
     74                return NULL;
     75        }
     76       
     77        ldr->sess = sess;
    7478        return ldr;
    7579}
     
    8892{
    8993        /* Get task ID. */
    90         ipc_call_t answer;
    91         aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
    92         int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
    93         if (rc != EOK) {
    94                 async_wait_for(req, NULL);
    95                 return rc;
    96         }
    97        
    98         sysarg_t retval;
    99         async_wait_for(req, &retval);
    100         return (int) retval;
     94        async_exch_t *exch = async_exchange_begin(ldr->sess);
     95       
     96        ipc_call_t answer;
     97        aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer);
     98        sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t));
     99       
     100        async_exchange_end(exch);
     101       
     102        if (rc != EOK) {
     103                async_wait_for(req, NULL);
     104                return (int) rc;
     105        }
     106       
     107        async_wait_for(req, &rc);
     108        return (int) rc;
    101109}
    102110
     
    112120int loader_set_cwd(loader_t *ldr)
    113121{
    114         char *cwd;
    115         size_t len;
    116 
    117         cwd = (char *) malloc(MAX_PATH_LEN + 1);
     122        char *cwd = (char *) malloc(MAX_PATH_LEN + 1);
    118123        if (!cwd)
    119124                return ENOMEM;
     125       
    120126        if (!getcwd(cwd, MAX_PATH_LEN + 1))
    121                 str_cpy(cwd, MAX_PATH_LEN + 1, "/");
    122         len = str_length(cwd);
    123        
    124         ipc_call_t answer;
    125         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer);
    126         int rc = async_data_write_start(ldr->phone_id, cwd, len);
     127                str_cpy(cwd, MAX_PATH_LEN + 1, "/");
     128       
     129        size_t len = str_length(cwd);
     130       
     131        async_exch_t *exch = async_exchange_begin(ldr->sess);
     132       
     133        ipc_call_t answer;
     134        aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer);
     135        sysarg_t rc = async_data_write_start(exch, cwd, len);
     136       
     137        async_exchange_end(exch);
    127138        free(cwd);
    128         if (rc != EOK) {
    129                 async_wait_for(req, NULL);
    130                 return rc;
    131         }
    132        
    133         sysarg_t retval;
    134         async_wait_for(req, &retval);
    135         return (int) retval;
     139       
     140        if (rc != EOK) {
     141                async_wait_for(req, NULL);
     142                return (int) rc;
     143        }
     144       
     145        async_wait_for(req, &rc);
     146        return (int) rc;
    136147}
    137148
     
    153164        char *pa = absolutize(path, &pa_len);
    154165        if (!pa)
    155                 return 0;
     166                return ENOMEM;
    156167       
    157168        /* Send program pathname */
    158         ipc_call_t answer;
    159         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
    160         int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
    161         if (rc != EOK) {
    162                 free(pa);
    163                 async_wait_for(req, NULL);
    164                 return rc;
    165         }
    166        
     169        async_exch_t *exch = async_exchange_begin(ldr->sess);
     170       
     171        ipc_call_t answer;
     172        aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer);
     173        sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len);
     174       
     175        async_exchange_end(exch);
    167176        free(pa);
    168177       
    169         sysarg_t retval;
    170         async_wait_for(req, &retval);
    171         return (int) retval;
     178        if (rc != EOK) {
     179                async_wait_for(req, NULL);
     180                return (int) rc;
     181        }
     182       
     183        async_wait_for(req, &rc);
     184        return (int) rc;
    172185}
    173186
     
    212225       
    213226        /* Send serialized arguments to the loader */
    214         ipc_call_t answer;
    215         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
    216         sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
    217         if (rc != EOK) {
    218                 async_wait_for(req, NULL);
    219                 return rc;
    220         }
    221        
    222         async_wait_for(req, &rc);
    223         if (rc != EOK)
    224                 return rc;
    225        
    226         /* Free temporary buffer */
     227        async_exch_t *exch = async_exchange_begin(ldr->sess);
     228       
     229        ipc_call_t answer;
     230        aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer);
     231        sysarg_t rc = async_data_write_start(exch, (void *) arg_buf,
     232            buffer_size);
     233       
     234        async_exchange_end(exch);
    227235        free(arg_buf);
    228236       
    229         return EOK;
     237        if (rc != EOK) {
     238                async_wait_for(req, NULL);
     239                return (int) rc;
     240        }
     241       
     242        async_wait_for(req, &rc);
     243        return (int) rc;
    230244}
    231245
     
    266280       
    267281        /* Send serialized files to the loader */
    268         ipc_call_t answer;
    269         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
    270         sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf,
     282        async_exch_t *exch = async_exchange_begin(ldr->sess);
     283       
     284        ipc_call_t answer;
     285        aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer);
     286        sysarg_t rc = async_data_write_start(exch, (void *) files_buf,
    271287            count * sizeof(fdi_node_t));
    272         if (rc != EOK) {
    273                 async_wait_for(req, NULL);
    274                 return rc;
    275         }
    276        
    277         async_wait_for(req, &rc);
    278         if (rc != EOK)
    279                 return rc;
    280        
    281         /* Free temporary buffer */
     288       
     289        async_exchange_end(exch);
    282290        free(files_buf);
    283291       
    284         return EOK;
     292        if (rc != EOK) {
     293                async_wait_for(req, NULL);
     294                return (int) rc;
     295        }
     296       
     297        async_wait_for(req, &rc);
     298        return (int) rc;
    285299}
    286300
     
    297311int loader_load_program(loader_t *ldr)
    298312{
    299         return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
     313        async_exch_t *exch = async_exchange_begin(ldr->sess);
     314        int rc = async_req_0_0(exch, LOADER_LOAD);
     315        async_exchange_end(exch);
     316       
     317        return rc;
    300318}
    301319
     
    306324 * the task and its thread is stopped.
    307325 *
    308  * After using this function, no further operations must be performed
    309  * on the loader structure. It should be de-allocated using free().
     326 * After using this function, no further operations can be performed
     327 * on the loader structure and it is deallocated.
    310328 *
    311329 * @param ldr Loader connection structure.
     
    316334int loader_run(loader_t *ldr)
    317335{
    318         int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
     336        async_exch_t *exch = async_exchange_begin(ldr->sess);
     337        int rc = async_req_0_0(exch, LOADER_RUN);
     338        async_exchange_end(exch);
     339       
    319340        if (rc != EOK)
    320341                return rc;
    321342       
    322         async_hangup(ldr->phone_id);
    323         ldr->phone_id = 0;
     343        async_hangup(ldr->sess);
     344        free(ldr);
     345       
    324346        return EOK;
    325347}
     
    327349/** Cancel the loader session.
    328350 *
    329  * Tells the loader not to load any program and terminate.
    330  * After using this function, no further operations must be performed
    331  * on the loader structure. It should be de-allocated using free().
     351 * Tell the loader not to load any program and terminate.
     352 * After using this function, no further operations can be performed
     353 * on the loader structure and it is deallocated.
    332354 *
    333355 * @param ldr Loader connection structure.
     
    338360void loader_abort(loader_t *ldr)
    339361{
    340         async_hangup(ldr->phone_id);
    341         ldr->phone_id = 0;
     362        async_hangup(ldr->sess);
     363        free(ldr);
    342364}
    343365
  • uspace/lib/c/generic/malloc.c

    r52a79081 ra33f0a6  
    6565#define BASE_ALIGN  16
    6666
     67/** Heap shrink granularity
     68 *
     69 * Try not to pump and stress the heap to much
     70 * by shrinking and enlarging it too often.
     71 * A heap area won't shrunk if it the released
     72 * free block is smaller than this constant.
     73 *
     74 */
     75#define SHRINK_GRANULARITY  (64 * PAGE_SIZE)
     76
    6777/** Overhead of each heap block. */
    6878#define STRUCT_OVERHEAD \
    6979        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    7080
     81/** Overhead of each area. */
     82#define AREA_OVERHEAD(size) \
     83        (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
     84
    7185/** Calculate real size of a heap block.
    7286 *
     
    86100 *
    87101 */
    88 #define AREA_FIRST_BLOCK(area) \
     102#define AREA_FIRST_BLOCK_HEAD(area) \
    89103        (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
     104
     105/** Get last block in heap area.
     106 *
     107 */
     108#define AREA_LAST_BLOCK_FOOT(area) \
     109        (((uintptr_t) (area)->end) - sizeof(heap_block_foot_t))
     110
     111/** Get header in heap block.
     112 *
     113 */
     114#define BLOCK_HEAD(foot) \
     115        ((heap_block_head_t *) \
     116            (((uintptr_t) (foot)) + sizeof(heap_block_foot_t) - (foot)->size))
    90117
    91118/** Get footer in heap block.
     
    94121#define BLOCK_FOOT(head) \
    95122        ((heap_block_foot_t *) \
    96             (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
     123            (((uintptr_t) (head)) + (head)->size - sizeof(heap_block_foot_t)))
    97124
    98125/** Heap area.
     
    115142        void *end;
    116143       
     144        /** Previous heap area */
     145        struct heap_area *prev;
     146       
    117147        /** Next heap area */
    118148        struct heap_area *next;
     
    157187
    158188/** Next heap block to examine (next fit algorithm) */
    159 static heap_block_head_t *next = NULL;
     189static heap_block_head_t *next_fit = NULL;
    160190
    161191/** Futex for thread-safe heap manipulation */
    162192static futex_t malloc_futex = FUTEX_INITIALIZER;
     193
     194#ifndef NDEBUG
     195
     196#define malloc_assert(expr) \
     197        do { \
     198                if (!(expr)) {\
     199                        futex_up(&malloc_futex); \
     200                        assert_abort(#expr, __FILE__, __LINE__); \
     201                } \
     202        } while (0)
     203
     204#else /* NDEBUG */
     205
     206#define malloc_assert(expr)
     207
     208#endif /* NDEBUG */
    163209
    164210/** Initialize a heap block
     
    202248        heap_block_head_t *head = (heap_block_head_t *) addr;
    203249       
    204         assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
     250        malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    205251       
    206252        heap_block_foot_t *foot = BLOCK_FOOT(head);
    207253       
    208         assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
    209         assert(head->size == foot->size);
     254        malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     255        malloc_assert(head->size == foot->size);
    210256}
    211257
    212258/** Check a heap area structure
    213259 *
     260 * Should be called only inside the critical section.
     261 *
    214262 * @param addr Address of the heap area.
    215263 *
     
    219267        heap_area_t *area = (heap_area_t *) addr;
    220268       
    221         assert(area->magic == HEAP_AREA_MAGIC);
    222         assert(area->start < area->end);
    223         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    224         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     269        malloc_assert(area->magic == HEAP_AREA_MAGIC);
     270        malloc_assert(addr == area->start);
     271        malloc_assert(area->start < area->end);
     272        malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     273        malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    225274}
    226275
    227276/** Create new heap area
    228277 *
    229  * @param start Preffered starting address of the new area.
    230  * @param size  Size of the area.
     278 * Should be called only inside the critical section.
     279 *
     280 * @param size Size of the area.
    231281 *
    232282 */
     
    248298       
    249299        area->start = astart;
    250         area->end = (void *)
    251             ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
     300        area->end = (void *) ((uintptr_t) astart + asize);
     301        area->prev = NULL;
    252302        area->next = NULL;
    253303        area->magic = HEAP_AREA_MAGIC;
    254304       
    255         void *block = (void *) AREA_FIRST_BLOCK(area);
     305        void *block = (void *) AREA_FIRST_BLOCK_HEAD(area);
    256306        size_t bsize = (size_t) (area->end - block);
    257307       
     
    262312                last_heap_area = area;
    263313        } else {
     314                area->prev = last_heap_area;
    264315                last_heap_area->next = area;
    265316                last_heap_area = area;
     
    271322/** Try to enlarge a heap area
    272323 *
     324 * Should be called only inside the critical section.
     325 *
    273326 * @param area Heap area to grow.
    274  * @param size Gross size of item to allocate (bytes).
     327 * @param size Gross size to grow (bytes).
     328 *
     329 * @return True if successful.
    275330 *
    276331 */
     
    282337        area_check(area);
    283338       
    284         size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
    285             PAGE_SIZE);
    286        
    287339        /* New heap area size */
    288         void *end = (void *)
    289             ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
     340        size_t gross_size = (size_t) (area->end - area->start) + size;
     341        size_t asize = ALIGN_UP(gross_size, PAGE_SIZE);
     342        void *end = (void *) ((uintptr_t) area->start + asize);
    290343       
    291344        /* Check for overflow */
     
    299352       
    300353        /* Add new free block */
    301         block_init(area->end, (size_t) (end - area->end), true, area);
     354        size_t net_size = (size_t) (end - area->end);
     355        if (net_size > 0)
     356                block_init(area->end, net_size, true, area);
    302357       
    303358        /* Update heap area parameters */
     
    309364/** Try to enlarge any of the heap areas
    310365 *
     366 * Should be called only inside the critical section.
     367 *
    311368 * @param size Gross size of item to allocate (bytes).
    312369 *
     
    318375       
    319376        /* First try to enlarge some existing area */
    320         heap_area_t *area;
    321         for (area = first_heap_area; area != NULL; area = area->next) {
     377        for (heap_area_t *area = first_heap_area; area != NULL;
     378            area = area->next) {
    322379                if (area_grow(area, size))
    323380                        return true;
     
    325382       
    326383        /* Eventually try to create a new area */
    327         return area_create(AREA_FIRST_BLOCK(size));
    328 }
    329 
    330 /** Try to shrink heap space
    331  *
     384        return area_create(AREA_OVERHEAD(size));
     385}
     386
     387/** Try to shrink heap
     388 *
     389 * Should be called only inside the critical section.
    332390 * In all cases the next pointer is reset.
    333391 *
    334  */
    335 static void heap_shrink(void)
    336 {
    337         next = NULL;
     392 * @param area Last modified heap area.
     393 *
     394 */
     395static void heap_shrink(heap_area_t *area)
     396{
     397        area_check(area);
     398       
     399        heap_block_foot_t *last_foot =
     400            (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area);
     401        heap_block_head_t *last_head = BLOCK_HEAD(last_foot);
     402       
     403        block_check((void *) last_head);
     404        malloc_assert(last_head->area == area);
     405       
     406        if (last_head->free) {
     407                /*
     408                 * The last block of the heap area is
     409                 * unused. The area might be potentially
     410                 * shrunk.
     411                 */
     412               
     413                heap_block_head_t *first_head =
     414                    (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area);
     415               
     416                block_check((void *) first_head);
     417                malloc_assert(first_head->area == area);
     418               
     419                size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
     420               
     421                if (first_head == last_head) {
     422                        /*
     423                         * The entire heap area consists of a single
     424                         * free heap block. This means we can get rid
     425                         * of it entirely.
     426                         */
     427                       
     428                        heap_area_t *prev = area->prev;
     429                        heap_area_t *next = area->next;
     430                       
     431                        if (prev != NULL) {
     432                                area_check(prev);
     433                                prev->next = next;
     434                        } else
     435                                first_heap_area = next;
     436                       
     437                        if (next != NULL) {
     438                                area_check(next);
     439                                next->prev = prev;
     440                        } else
     441                                last_heap_area = prev;
     442                       
     443                        as_area_destroy(area->start);
     444                } else if (shrink_size >= SHRINK_GRANULARITY) {
     445                        /*
     446                         * Make sure that we always shrink the area
     447                         * by a multiple of page size and update
     448                         * the block layout accordingly.
     449                         */
     450                       
     451                        size_t asize = (size_t) (area->end - area->start) - shrink_size;
     452                        void *end = (void *) ((uintptr_t) area->start + asize);
     453                       
     454                        /* Resize the address space area */
     455                        int ret = as_area_resize(area->start, asize, 0);
     456                        if (ret != EOK)
     457                                abort();
     458                       
     459                        /* Update heap area parameters */
     460                        area->end = end;
     461                        size_t excess = ((size_t) area->end) - ((size_t) last_head);
     462                       
     463                        if (excess > 0) {
     464                                if (excess >= STRUCT_OVERHEAD) {
     465                                        /*
     466                                         * The previous block cannot be free and there
     467                                         * is enough free space left in the area to
     468                                         * create a new free block.
     469                                         */
     470                                        block_init((void *) last_head, excess, true, area);
     471                                } else {
     472                                        /*
     473                                         * The excess is small. Therefore just enlarge
     474                                         * the previous block.
     475                                         */
     476                                        heap_block_foot_t *prev_foot = (heap_block_foot_t *)
     477                                            (((uintptr_t) last_head) - sizeof(heap_block_foot_t));
     478                                        heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot);
     479                                       
     480                                        block_check((void *) prev_head);
     481                                       
     482                                        block_init(prev_head, prev_head->size + excess,
     483                                            prev_head->free, area);
     484                                }
     485                        }
     486                }
     487        }
     488       
     489        next_fit = NULL;
    338490}
    339491
     
    362514static void split_mark(heap_block_head_t *cur, const size_t size)
    363515{
    364         assert(cur->size >= size);
     516        malloc_assert(cur->size >= size);
    365517       
    366518        /* See if we should split the block. */
     
    398550{
    399551        area_check((void *) area);
    400         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
    401         assert((void *) first_block < area->end);
    402        
    403         heap_block_head_t *cur;
    404         for (cur = first_block; (void *) cur < area->end;
     552        malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     553        malloc_assert((void *) first_block < area->end);
     554       
     555        for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
    405556            cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
    406557                block_check(cur);
     
    425576                                split_mark(cur, real_size);
    426577                               
    427                                 next = cur;
     578                                next_fit = cur;
    428579                                return addr;
    429580                        } else {
     
    436587                                         * data in (including alignment).
    437588                                         */
    438                                         if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
     589                                        if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    439590                                                /*
    440591                                                 * There is a block before the current block.
     
    477628                                                split_mark(next_head, real_size);
    478629                                               
    479                                                 next = next_head;
     630                                                next_fit = next_head;
    480631                                                return aligned;
    481632                                        } else {
     
    496647                                                        size_t reduced_size = cur->size - excess;
    497648                                                        cur = (heap_block_head_t *)
    498                                                             (AREA_FIRST_BLOCK(area) + excess);
     649                                                            (AREA_FIRST_BLOCK_HEAD(area) + excess);
    499650                                                       
    500                                                         block_init((void *) AREA_FIRST_BLOCK(area), excess,
    501                                                             true, area);
     651                                                        block_init((void *) AREA_FIRST_BLOCK_HEAD(area),
     652                                                            excess, true, area);
    502653                                                        block_init(cur, reduced_size, true, area);
    503654                                                        split_mark(cur, real_size);
    504655                                                       
    505                                                         next = cur;
     656                                                        next_fit = cur;
    506657                                                        return aligned;
    507658                                                }
     
    527678static void *malloc_internal(const size_t size, const size_t align)
    528679{
    529         assert(first_heap_area != NULL);
     680        malloc_assert(first_heap_area != NULL);
    530681       
    531682        if (align == 0)
     
    541692       
    542693        /* Try the next fit approach */
    543         split = next;
     694        split = next_fit;
    544695       
    545696        if (split != NULL) {
     
    552703       
    553704        /* Search the entire heap */
    554         heap_area_t *area;
    555         for (area = first_heap_area; area != NULL; area = area->next) {
     705        for (heap_area_t *area = first_heap_area; area != NULL;
     706            area = area->next) {
    556707                heap_block_head_t *first = (heap_block_head_t *)
    557                     AREA_FIRST_BLOCK(area);
     708                    AREA_FIRST_BLOCK_HEAD(area);
    558709               
    559710                void *addr = malloc_area(area, first, split, real_size,
     
    652803       
    653804        block_check(head);
    654         assert(!head->free);
     805        malloc_assert(!head->free);
    655806       
    656807        heap_area_t *area = head->area;
    657808       
    658809        area_check(area);
    659         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    660         assert((void *) head < area->end);
     810        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     811        malloc_assert((void *) head < area->end);
    661812       
    662813        void *ptr = NULL;
     
    675826                        block_init((void *) head + real_size,
    676827                            orig_size - real_size, true, area);
    677                         heap_shrink();
     828                        heap_shrink(area);
    678829                }
    679830               
     
    697848                       
    698849                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    699                         next = NULL;
     850                        next_fit = NULL;
    700851                } else
    701852                        reloc = true;
     
    729880       
    730881        block_check(head);
    731         assert(!head->free);
     882        malloc_assert(!head->free);
    732883       
    733884        heap_area_t *area = head->area;
    734885       
    735886        area_check(area);
    736         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    737         assert((void *) head < area->end);
     887        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     888        malloc_assert((void *) head < area->end);
    738889       
    739890        /* Mark the block itself as free. */
     
    751902       
    752903        /* Look at the previous block. If it is free, merge the two. */
    753         if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
     904        if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    754905                heap_block_foot_t *prev_foot =
    755906                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    765916        }
    766917       
    767         heap_shrink();
     918        heap_shrink(area);
    768919       
    769920        futex_up(&malloc_futex);
    770921}
    771922
     923void *heap_check(void)
     924{
     925        futex_down(&malloc_futex);
     926       
     927        if (first_heap_area == NULL) {
     928                futex_up(&malloc_futex);
     929                return (void *) -1;
     930        }
     931       
     932        /* Walk all heap areas */
     933        for (heap_area_t *area = first_heap_area; area != NULL;
     934            area = area->next) {
     935               
     936                /* Check heap area consistency */
     937                if ((area->magic != HEAP_AREA_MAGIC) ||
     938                    ((void *) area != area->start) ||
     939                    (area->start >= area->end) ||
     940                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
     941                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
     942                        futex_up(&malloc_futex);
     943                        return (void *) area;
     944                }
     945               
     946                /* Walk all heap blocks */
     947                for (heap_block_head_t *head = (heap_block_head_t *)
     948                    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
     949                    head = (heap_block_head_t *) (((void *) head) + head->size)) {
     950                       
     951                        /* Check heap block consistency */
     952                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
     953                                futex_up(&malloc_futex);
     954                                return (void *) head;
     955                        }
     956                       
     957                        heap_block_foot_t *foot = BLOCK_FOOT(head);
     958                       
     959                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
     960                            (head->size != foot->size)) {
     961                                futex_up(&malloc_futex);
     962                                return (void *) foot;
     963                        }
     964                }
     965        }
     966       
     967        futex_up(&malloc_futex);
     968       
     969        return NULL;
     970}
     971
    772972/** @}
    773973 */
  • uspace/lib/c/generic/net/icmp_api.c

    r52a79081 ra33f0a6  
    5454 * timeout occurs.
    5555 *
    56  * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
     56 * @param[in] sess The ICMP session.
    5757 * @param[in] size      The message data length in bytes.
    5858 * @param[in] timeout   The timeout in milliseconds.
     
    7373 */
    7474int
    75 icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,
     75icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl,
    7676    ip_tos_t tos, int dont_fragment, const struct sockaddr *addr,
    7777    socklen_t addrlen)
     
    8282        if (addrlen <= 0)
    8383                return EINVAL;
    84 
    85         message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
     84       
     85        async_exch_t *exch = async_exchange_begin(sess);
     86       
     87        message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl,
    8688            tos, (sysarg_t) dont_fragment, NULL);
    87 
     89       
    8890        /* Send the address */
    89         async_data_write_start(icmp_phone, addr, (size_t) addrlen);
     91        async_data_write_start(exch, addr, (size_t) addrlen);
     92       
     93        async_exchange_end(exch);
    9094
    9195        async_wait_for(message_id, &result);
  • uspace/lib/c/generic/net/icmp_common.c

    r52a79081 ra33f0a6  
    4545/** Connect to the ICMP module.
    4646 *
    47  * @param[in] timeout Connection timeout in microseconds, zero
    48  *                    for no timeout.
    49  *
    50  * @return ICMP module phone on success.
    51  * @return ETIMEOUT if the connection timeouted.
     47 * @return ICMP module session.
    5248 *
    5349 */
    54 int icmp_connect_module(suseconds_t timeout)
     50async_sess_t *icmp_connect_module(void)
    5551{
    56         return connect_to_service_timeout(SERVICE_ICMP, timeout);
     52        return connect_to_service(SERVICE_ICMP);
    5753}
    5854
  • uspace/lib/c/generic/net/modules.c

    r52a79081 ra33f0a6  
    4545#include <ipc/services.h>
    4646#include <net/modules.h>
    47 
    48 /** The time between connect requests in microseconds. */
    49 #define MODULE_WAIT_TIME        (10 * 1000)
     47#include <ns.h>
    5048
    5149/** Answer a call.
     
    9593}
    9694
    97 /** Create bidirectional connection with the needed module service and registers
     95/** Create bidirectional connection with the needed module service and register
    9896 * the message receiver.
    9997 *
    100  * @param[in] need      The needed module service.
    101  * @param[in] arg1      The first parameter.
    102  * @param[in] arg2      The second parameter.
    103  * @param[in] arg3      The third parameter.
    104  * @param[in] client_receiver The message receiver.
    105  *
    106  * @return              The phone of the needed service.
    107  * @return              Other error codes as defined for the ipc_connect_to_me()
    108  *                      function.
    109  */
    110 int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    111     async_client_conn_t client_receiver)
    112 {
    113         return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
    114 }
    115 
    116 /** Create bidirectional connection with the needed module service and registers
    117  * the message receiver.
    118  *
    119  * @param[in] need      The needed module service.
    120  * @param[in] arg1      The first parameter.
    121  * @param[in] arg2      The second parameter.
    122  * @param[in] arg3      The third parameter.
    123  * @param[in] client_receiver The message receiver.
    124  * @param[in] timeout   The connection timeout in microseconds. No timeout if
    125  *                      set to zero (0).
    126  *
    127  * @return              The phone of the needed service.
    128  * @return              ETIMEOUT if the connection timeouted.
    129  * @return              Other error codes as defined for the ipc_connect_to_me()
    130  *                      function.
    131  *
    132  */
    133 int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2,
    134     sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
     98 * @param[in] need            Needed module service.
     99 * @param[in] arg1            First parameter.
     100 * @param[in] arg2            Second parameter.
     101 * @param[in] arg3            Third parameter.
     102 * @param[in] client_receiver Message receiver.
     103 *
     104 * @return Session to the needed service.
     105 * @return Other error codes as defined for the async_connect_to_me()
     106 *         function.
     107 *
     108 */
     109async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2,
     110    sysarg_t arg3, async_client_conn_t client_receiver)
    135111{
    136112        /* Connect to the needed service */
    137         int phone = connect_to_service_timeout(need, timeout);
    138         if (phone >= 0) {
     113        async_sess_t *sess = connect_to_service(need);
     114        if (sess != NULL) {
    139115                /* Request the bidirectional connection */
    140                 int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
     116                async_exch_t *exch = async_exchange_begin(sess);
     117                int rc = async_connect_to_me(exch, arg1, arg2, arg3,
     118                    client_receiver, NULL);
     119                async_exchange_end(exch);
     120               
    141121                if (rc != EOK) {
    142                         async_hangup(phone);
    143                         return rc;
     122                        async_hangup(sess);
     123                        errno = rc;
     124                        return NULL;
    144125                }
    145126        }
    146127       
    147         return phone;
    148 }
    149 
    150 /** Connects to the needed module.
    151  *
    152  * @param[in] need      The needed module service.
    153  * @return              The phone of the needed service.
    154  */
    155 int connect_to_service(services_t need)
    156 {
    157         return connect_to_service_timeout(need, 0);
    158 }
    159 
    160 /** Connects to the needed module.
    161  *
    162  *  @param[in] need     The needed module service.
    163  *  @param[in] timeout  The connection timeout in microseconds. No timeout if
    164  *                      set to zero (0).
    165  *  @return             The phone of the needed service.
    166  *  @return             ETIMEOUT if the connection timeouted.
    167  */
    168 int connect_to_service_timeout(services_t need, suseconds_t timeout)
    169 {
    170         int phone;
    171 
    172         /* If no timeout is set */
    173         if (timeout <= 0)
    174                 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
    175 
    176         while (true) {
    177                 phone = async_connect_me_to(PHONE_NS, need, 0, 0);
    178                 if ((phone >= 0) || (phone != ENOENT))
    179                         return phone;
    180 
    181                 /* Abort if no time is left */
    182                 if (timeout <= 0)
    183                         return ETIMEOUT;
    184 
    185                 /* Wait the minimum of the module wait time and the timeout */
    186                 usleep((timeout <= MODULE_WAIT_TIME) ?
    187                     timeout : MODULE_WAIT_TIME);
    188                 timeout -= MODULE_WAIT_TIME;
    189         }
    190 }
    191 
    192 /** Replies the data to the other party.
    193  *
    194  * @param[in] data      The data buffer to be sent.
     128        return sess;
     129}
     130
     131/** Connect to the needed module.
     132 *
     133 * @param[in] need Needed module service.
     134 *
     135 * @return Session to the needed service.
     136 * @return NULL if the connection timeouted.
     137 *
     138 */
     139async_sess_t *connect_to_service(services_t need)
     140{
     141        return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0);
     142}
     143
     144/** Reply the data to the other party.
     145 *
     146 * @param[in] data        The data buffer to be sent.
    195147 * @param[in] data_length The buffer length.
    196  * @return              EOK on success.
    197  * @return              EINVAL if the client does not expect the data.
    198  * @return              EOVERFLOW if the client does not expect all the data.
    199  *                      Only partial data are transfered.
    200  * @return              Other error codes as defined for the
    201  *                      async_data_read_finalize() function.
     148 *
     149 * @return EOK on success.
     150 * @return EINVAL if the client does not expect the data.
     151 * @return EOVERFLOW if the client does not expect all the data.
     152 *         Only partial data are transfered.
     153 * @return Other error codes as defined for the
     154 *         async_data_read_finalize() function.
     155 *
    202156 */
    203157int data_reply(void *data, size_t data_length)
     
    205159        size_t length;
    206160        ipc_callid_t callid;
    207 
     161       
    208162        /* Fetch the request */
    209163        if (!async_data_read_receive(&callid, &length))
    210164                return EINVAL;
    211 
     165       
    212166        /* Check the requested data size */
    213167        if (length < data_length) {
     
    215169                return EOVERFLOW;
    216170        }
    217 
     171       
    218172        /* Send the data */
    219173        return async_data_read_finalize(callid, data, data_length);
  • uspace/lib/c/generic/net/socket_client.c

    r52a79081 ra33f0a6  
    6464#define SOCKET_MAX_ACCEPTED_SIZE        0
    6565
    66 /** Default timeout for connections in microseconds. */
    67 #define SOCKET_CONNECT_TIMEOUT  (1 * 1000 * 1000)
    68 
    6966/**
    7067 * Maximum number of random attempts to find a new socket identifier before
     
    8683        /** Socket identifier. */
    8784        int socket_id;
    88         /** Parent module phone. */
    89         int phone;
     85        /** Parent module session. */
     86        async_sess_t *sess;
    9087        /** Parent module service. */
    9188        services_t service;
     
    146143/** Socket client library global data. */
    147144static struct socket_client_globals {
    148         /** TCP module phone. */
    149         int tcp_phone;
    150         /** UDP module phone. */
    151         int udp_phone;
    152 
    153 //      /** The last socket identifier.
    154 //       */
    155 //      int last_id;
     145        /** TCP module session. */
     146        async_sess_t *tcp_sess;
     147        /** UDP module session. */
     148        async_sess_t *udp_sess;
    156149
    157150        /** Active sockets. */
     
    166159        fibril_rwlock_t lock;
    167160} socket_globals = {
    168         .tcp_phone = -1,
    169         .udp_phone = -1,
    170 //      .last_id = 0,
     161        .tcp_sess = NULL,
     162        .udp_sess = NULL,
    171163        .sockets = NULL,
    172164        .lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock)
     
    202194 * @param[in] iid       The initial message identifier.
    203195 * @param[in] icall     The initial message call structure.
    204  */
    205 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall)
     196 * @param[in] arg       Local argument.
     197 */
     198static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg)
    206199{
    207200        ipc_callid_t callid;
     
    281274}
    282275
    283 /** Returns the TCP module phone.
    284  *
    285  * Connects to the TCP module if necessary.
    286  *
    287  * @return              The TCP module phone.
    288  * @return              Other error codes as defined for the
    289  *                      bind_service_timeout() function.
    290  */
    291 static int socket_get_tcp_phone(void)
    292 {
    293         if (socket_globals.tcp_phone < 0) {
    294                 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP,
    295                     0, 0, SERVICE_TCP, socket_connection,
    296                     SOCKET_CONNECT_TIMEOUT);
    297         }
    298 
    299         return socket_globals.tcp_phone;
    300 }
    301 
    302 /** Returns the UDP module phone.
    303  *
    304  * Connects to the UDP module if necessary.
    305  *
    306  * @return              The UDP module phone.
    307  * @return              Other error codes as defined for the
    308  *                      bind_service_timeout() function.
    309  */
    310 static int socket_get_udp_phone(void)
    311 {
    312         if (socket_globals.udp_phone < 0) {
    313                 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP,
    314                     0, 0, SERVICE_UDP, socket_connection,
    315                     SOCKET_CONNECT_TIMEOUT);
    316         }
    317 
    318         return socket_globals.udp_phone;
     276/** Return the TCP module session.
     277 *
     278 * Connect to the TCP module if necessary.
     279 *
     280 * @return The TCP module session.
     281 *
     282 */
     283static async_sess_t *socket_get_tcp_sess(void)
     284{
     285        if (socket_globals.tcp_sess == NULL) {
     286                socket_globals.tcp_sess = bind_service(SERVICE_TCP,
     287                    0, 0, SERVICE_TCP, socket_connection);
     288        }
     289
     290        return socket_globals.tcp_sess;
     291}
     292
     293/** Return the UDP module session.
     294 *
     295 * Connect to the UDP module if necessary.
     296 *
     297 * @return The UDP module session.
     298 *
     299 */
     300static async_sess_t *socket_get_udp_sess(void)
     301{
     302        if (socket_globals.udp_sess == NULL) {
     303                socket_globals.udp_sess = bind_service(SERVICE_UDP,
     304                    0, 0, SERVICE_UDP, socket_connection);
     305        }
     306
     307        return socket_globals.udp_sess;
    319308}
    320309
     
    332321        sockets = socket_get_sockets();
    333322        count = 0;
    334 //      socket_id = socket_globals.last_id;
    335323
    336324        do {
     
    345333                        if (socket_id < INT_MAX) {
    346334                                ++socket_id;
    347 /*                      } else if(socket_globals.last_id) {
    348  *                              socket_globals.last_id = 0;
    349  *                              socket_id = 1;
    350  */                     } else {
     335                        } else {
    351336                                return ELIMIT;
    352337                        }
    353338                }
    354339        } while (sockets_find(sockets, socket_id));
    355 
    356 //      last_id = socket_id
     340       
    357341        return socket_id;
    358342}
     
    361345 *
    362346 * @param[in,out] socket The socket to be initialized.
    363  * @param[in] socket_id The new socket identifier.
    364  * @param[in] phone     The parent module phone.
    365  * @param[in] service   The parent module service.
    366  */
    367 static void
    368 socket_initialize(socket_t *socket, int socket_id, int phone,
    369     services_t service)
     347 * @param[in] socket_id  The new socket identifier.
     348 * @param[in] sess       The parent module session.
     349 * @param[in] service    The parent module service.
     350 */
     351static void socket_initialize(socket_t *socket, int socket_id,
     352    async_sess_t *sess, services_t service)
    370353{
    371354        socket->socket_id = socket_id;
    372         socket->phone = phone;
     355        socket->sess = sess;
    373356        socket->service = service;
    374357        dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
     
    395378 * @return              Other error codes as defined for the NET_SOCKET message.
    396379 * @return              Other error codes as defined for the
    397  *                      bind_service_timeout() function.
     380 *                      bind_service() function.
    398381 */
    399382int socket(int domain, int type, int protocol)
    400383{
    401384        socket_t *socket;
    402         int phone;
     385        async_sess_t *sess;
    403386        int socket_id;
    404387        services_t service;
     
    417400                        switch (protocol) {
    418401                        case IPPROTO_TCP:
    419                                 phone = socket_get_tcp_phone();
     402                                sess = socket_get_tcp_sess();
    420403                                service = SERVICE_TCP;
    421404                                break;
     
    432415                        switch (protocol) {
    433416                        case IPPROTO_UDP:
    434                                 phone = socket_get_udp_phone();
     417                                sess = socket_get_udp_sess();
    435418                                service = SERVICE_UDP;
    436419                                break;
     
    453436        }
    454437
    455         if (phone < 0)
    456                 return phone;
     438        if (sess == NULL)
     439                return ENOENT;
    457440
    458441        /* Create a new socket structure */
     
    471454                return socket_id;
    472455        }
    473 
    474         rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
     456       
     457        async_exch_t *exch = async_exchange_begin(sess);
     458        rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL,
    475459            &fragment_size, &header_size);
     460        async_exchange_end(exch);
     461       
    476462        if (rc != EOK) {
    477463                fibril_rwlock_write_unlock(&socket_globals.lock);
     
    484470
    485471        /* Finish the new socket initialization */
    486         socket_initialize(socket, socket_id, phone, service);
     472        socket_initialize(socket, socket_id, sess, service);
    487473        /* Store the new socket */
    488474        rc = sockets_add(socket_get_sockets(), socket_id, socket);
     
    493479                dyn_fifo_destroy(&socket->accepted);
    494480                free(socket);
    495                 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
     481               
     482                exch = async_exchange_begin(sess);
     483                async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
    496484                    service);
     485                async_exchange_end(exch);
     486               
    497487                return rc;
    498488        }
     
    538528
    539529        /* Request the message */
    540         message_id = async_send_3(socket->phone, message,
     530        async_exch_t *exch = async_exchange_begin(socket->sess);
     531        message_id = async_send_3(exch, message,
    541532            (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
    542533        /* Send the address */
    543         async_data_write_start(socket->phone, data, datalength);
     534        async_data_write_start(exch, data, datalength);
     535        async_exchange_end(exch);
    544536
    545537        fibril_rwlock_read_unlock(&socket_globals.lock);
     
    598590
    599591        /* Request listen backlog change */
    600         result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN,
     592        async_exch_t *exch = async_exchange_begin(socket->sess);
     593        result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN,
    601594            (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
     595        async_exchange_end(exch);
    602596
    603597        fibril_rwlock_read_unlock(&socket_globals.lock);
     
    669663                return socket_id;
    670664        }
    671         socket_initialize(new_socket, socket_id, socket->phone,
     665        socket_initialize(new_socket, socket_id, socket->sess,
    672666            socket->service);
    673667        result = sockets_add(socket_get_sockets(), new_socket->socket_id,
     
    681675
    682676        /* Request accept */
    683         message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT,
     677        async_exch_t *exch = async_exchange_begin(socket->sess);
     678        message_id = async_send_5(exch, NET_SOCKET_ACCEPT,
    684679            (sysarg_t) socket->socket_id, 0, socket->service, 0,
    685680            new_socket->socket_id, &answer);
    686681
    687682        /* Read address */
    688         async_data_read_start(socket->phone, cliaddr, *addrlen);
     683        async_data_read_start(exch, cliaddr, *addrlen);
     684        async_exchange_end(exch);
     685       
    689686        fibril_rwlock_write_unlock(&socket_globals.lock);
    690687        async_wait_for(message_id, &ipc_result);
     
    780777
    781778        /* Request close */
    782         rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE,
     779        async_exch_t *exch = async_exchange_begin(socket->sess);
     780        rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE,
    783781            (sysarg_t) socket->socket_id, 0, socket->service);
     782        async_exchange_end(exch);
     783       
    784784        if (rc != EOK) {
    785785                fibril_rwlock_write_unlock(&socket_globals.lock);
     
    853853
    854854        /* Request send */
    855         message_id = async_send_5(socket->phone, message,
     855        async_exch_t *exch = async_exchange_begin(socket->sess);
     856       
     857        message_id = async_send_5(exch, message,
    856858            (sysarg_t) socket->socket_id,
    857859            (fragments == 1 ? datalength : socket->data_fragment_size),
     
    860862        /* Send the address if given */
    861863        if (!toaddr ||
    862             (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
     864            (async_data_write_start(exch, toaddr, addrlen) == EOK)) {
    863865                if (fragments == 1) {
    864866                        /* Send all if only one fragment */
    865                         async_data_write_start(socket->phone, data, datalength);
     867                        async_data_write_start(exch, data, datalength);
    866868                } else {
    867869                        /* Send the first fragment */
    868                         async_data_write_start(socket->phone, data,
     870                        async_data_write_start(exch, data,
    869871                            socket->data_fragment_size - socket->header_size);
    870872                        data = ((const uint8_t *) data) +
     
    873875                        /* Send the middle fragments */
    874876                        while (--fragments > 1) {
    875                                 async_data_write_start(socket->phone, data,
     877                                async_data_write_start(exch, data,
    876878                                    socket->data_fragment_size);
    877879                                data = ((const uint8_t *) data) +
     
    880882
    881883                        /* Send the last fragment */
    882                         async_data_write_start(socket->phone, data,
     884                        async_data_write_start(exch, data,
    883885                            (datalength + socket->header_size) %
    884886                            socket->data_fragment_size);
    885887                }
    886888        }
     889       
     890        async_exchange_end(exch);
    887891
    888892        async_wait_for(message_id, &result);
     
    10261030                return 0;
    10271031        }
     1032       
     1033        async_exch_t *exch = async_exchange_begin(socket->sess);
    10281034
    10291035        /* Prepare lengths if more fragments */
     
    10381044
    10391045                /* Request packet data */
    1040                 message_id = async_send_4(socket->phone, message,
     1046                message_id = async_send_4(exch, message,
    10411047                    (sysarg_t) socket->socket_id, 0, socket->service,
    10421048                    (sysarg_t) flags, &answer);
     
    10441050                /* Read the address if desired */
    10451051                if(!fromaddr ||
    1046                     (async_data_read_start(socket->phone, fromaddr,
     1052                    (async_data_read_start(exch, fromaddr,
    10471053                    *addrlen) == EOK)) {
    10481054                        /* Read the fragment lengths */
    1049                         if (async_data_read_start(socket->phone, lengths,
     1055                        if (async_data_read_start(exch, lengths,
    10501056                            sizeof(int) * (fragments + 1)) == EOK) {
    10511057                                if (lengths[fragments] <= datalength) {
     
    10541060                                        for (index = 0; index < fragments;
    10551061                                            ++index) {
    1056                                                 async_data_read_start(
    1057                                                     socket->phone, data,
     1062                                                async_data_read_start(exch, data,
    10581063                                                    lengths[index]);
    10591064                                                data = ((uint8_t *) data) +
     
    10671072        } else { /* fragments == 1 */
    10681073                /* Request packet data */
    1069                 message_id = async_send_4(socket->phone, message,
     1074                message_id = async_send_4(exch, message,
    10701075                    (sysarg_t) socket->socket_id, 0, socket->service,
    10711076                    (sysarg_t) flags, &answer);
     
    10731078                /* Read the address if desired */
    10741079                if (!fromaddr ||
    1075                     (async_data_read_start(socket->phone, fromaddr,
    1076                         *addrlen) == EOK)) {
     1080                    (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) {
    10771081                        /* Read all if only one fragment */
    1078                         async_data_read_start(socket->phone, data, datalength);
     1082                        async_data_read_start(exch, data, datalength);
    10791083                }
    10801084        }
     1085       
     1086        async_exchange_end(exch);
    10811087
    10821088        async_wait_for(message_id, &ipc_result);
     
    11901196
    11911197        /* Request option value */
    1192         message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
     1198        async_exch_t *exch = async_exchange_begin(socket->sess);
     1199       
     1200        message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT,
    11931201            (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
    11941202            NULL);
    11951203
    11961204        /* Read the length */
    1197         if (async_data_read_start(socket->phone, optlen,
     1205        if (async_data_read_start(exch, optlen,
    11981206            sizeof(*optlen)) == EOK) {
    11991207                /* Read the value */
    1200                 async_data_read_start(socket->phone, value, *optlen);
    1201         }
     1208                async_data_read_start(exch, value, *optlen);
     1209        }
     1210       
     1211        async_exchange_end(exch);
    12021212
    12031213        fibril_rwlock_read_unlock(&socket_globals.lock);
  • uspace/lib/c/generic/ns_obsolete.c

    r52a79081 ra33f0a6  
    3434
    3535#include <async.h>
    36 #include <ipc/ns.h>
     36#include <async_obsolete.h>
     37#include <ns_obsolete.h>
     38#include <kernel/ipc/ipc_methods.h>
    3739
    38 int service_register(sysarg_t service)
     40int service_obsolete_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    3941{
    40         return async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
     42        return async_obsolete_connect_me_to(PHONE_NS, service, arg2, arg3);
    4143}
    4244
    43 int service_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
     45int service_obsolete_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    4446{
    45         return async_connect_me_to(PHONE_NS, service, arg2, arg3);
    46 }
    47 
    48 int service_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    49 {
    50         return async_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
     47        return async_obsolete_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
    5148}
    5249
  • uspace/lib/c/generic/private/async.h

    r52a79081 ra33f0a6  
    7979} awaiter_t;
    8080
     81/** Message data */
     82typedef struct {
     83        awaiter_t wdata;
     84       
     85        /** If reply was received. */
     86        bool done;
     87       
     88        /** Pointer to where the answer data is stored. */
     89        ipc_call_t *dataptr;
     90       
     91        sysarg_t retval;
     92} amsg_t;
     93
    8194extern void __async_init(void);
    8295extern void async_insert_timeout(awaiter_t *);
     96extern void reply_received(void *, int, ipc_call_t *);
    8397
    8498#endif
  • uspace/lib/c/generic/private/ns.h

    r52a79081 ra33f0a6  
    3333 */
    3434
    35 #ifndef LIBC_PRIVATE_ASYNC_SESS_H_
    36 #define LIBC_PRIVATE_ASYNC_SESS_H_
     35#ifndef LIBC_PRIVATE_NS_H_
     36#define LIBC_PRIVATE_NS_H_
    3737
    38 extern void __async_sess_init(void);
     38#include <async.h>
     39
     40extern async_sess_t *session_ns;
    3941
    4042#endif
  • uspace/lib/c/generic/str.c

    r52a79081 ra33f0a6  
    553553
    554554        dstr_size = str_size(dest);
     555        if (dstr_size >= size)
     556                return;
     557       
    555558        str_cpy(dest + dstr_size, size - dstr_size, src);
     559}
     560
     561/** Convert space-padded ASCII to string.
     562 *
     563 * Common legacy text encoding in hardware is 7-bit ASCII fitted into
     564 * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
     565 * (ASCII 0x20). Convert space-padded ascii to string representation.
     566 *
     567 * If the text does not fit into the destination buffer, the function converts
     568 * as many characters as possible and returns EOVERFLOW.
     569 *
     570 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
     571 * converted anyway and invalid characters are replaced with question marks
     572 * (U_SPECIAL) and the function returns EIO.
     573 *
     574 * Regardless of return value upon return @a dest will always be well-formed.
     575 *
     576 * @param dest          Destination buffer
     577 * @param size          Size of destination buffer
     578 * @param src           Space-padded ASCII.
     579 * @param n             Size of the source buffer in bytes.
     580 *
     581 * @return              EOK on success, EOVERFLOW if the text does not fit
     582 *                      destination buffer, EIO if the text contains
     583 *                      non-ASCII bytes.
     584 */
     585int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
     586{
     587        size_t sidx;
     588        size_t didx;
     589        size_t dlast;
     590        uint8_t byte;
     591        int rc;
     592        int result;
     593
     594        /* There must be space for a null terminator in the buffer. */
     595        assert(size > 0);
     596        result = EOK;
     597
     598        didx = 0;
     599        dlast = 0;
     600        for (sidx = 0; sidx < n; ++sidx) {
     601                byte = src[sidx];
     602                if (!ascii_check(byte)) {
     603                        byte = U_SPECIAL;
     604                        result = EIO;
     605                }
     606
     607                rc = chr_encode(byte, dest, &didx, size - 1);
     608                if (rc != EOK) {
     609                        assert(rc == EOVERFLOW);
     610                        dest[didx] = '\0';
     611                        return rc;
     612                }
     613
     614                /* Remember dest index after last non-empty character */
     615                if (byte != 0x20)
     616                        dlast = didx;
     617        }
     618
     619        /* Terminate string after last non-empty character */
     620        dest[dlast] = '\0';
     621        return result;
    556622}
    557623
  • uspace/lib/c/generic/str_error.c

    r52a79081 ra33f0a6  
    3333 */
    3434
     35#include <errno.h>
    3536#include <str_error.h>
    3637#include <stdio.h>
     
    6364static fibril_local char noerr[NOERR_LEN];
    6465
    65 const char *str_error(const int errno)
     66const char *str_error(const int e)
    6667{
    67         if ((errno <= 0) && (errno >= MIN_ERRNO))
    68                 return err_desc[-errno];
     68        if ((e <= 0) && (e >= MIN_ERRNO))
     69                return err_desc[-e];
    6970       
    70         snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno);
     71        /* Ad hoc descriptions of error codes interesting for USB. */
     72        // FIXME: integrate these as first-class error values
     73        switch (e) {
     74                case EBADCHECKSUM:
     75                        return "Bad checksum";
     76                case ESTALL:
     77                        return "Operation stalled";
     78                case EAGAIN:
     79                        return "Resource temporarily unavailable";
     80                case EEMPTY:
     81                        return "Resource is empty";
     82                default:
     83                        break;
     84        }
     85
     86        snprintf(noerr, NOERR_LEN, "Unkown error code %d", e);
    7187        return noerr;
    7288}
  • uspace/lib/c/generic/task.c

    r52a79081 ra33f0a6  
    3535
    3636#include <task.h>
    37 #include <libc.h>
    38 #include <stdlib.h>
    39 #include <errno.h>
    4037#include <loader/loader.h>
    4138#include <stdarg.h>
     
    4340#include <ipc/ns.h>
    4441#include <macros.h>
     42#include <assert.h>
    4543#include <async.h>
     44#include <errno.h>
     45#include <malloc.h>
     46#include <libc.h>
     47#include "private/ns.h"
    4648
    4749task_id_t task_get_id(void)
     
    6870int task_set_name(const char *name)
    6971{
     72        assert(name);
     73       
    7074        return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name));
    7175}
     
    8892 * loader API. Arguments are passed as a null-terminated array of strings.
    8993 *
    90  * @param id    If not NULL, the ID of the task is stored here on success.
    91  * @param path  Pathname of the binary to execute.
    92  * @param argv  Command-line arguments.
    93  *
    94  * @return      Zero on success or negative error code.
     94 * @param id   If not NULL, the ID of the task is stored here on success.
     95 * @param path Pathname of the binary to execute.
     96 * @param argv Command-line arguments.
     97 *
     98 * @return Zero on success or negative error code.
     99 *
    95100 */
    96101int task_spawnv(task_id_t *id, const char *path, const char *const args[])
    97102{
    98         loader_t *ldr;
    99         task_id_t task_id;
    100         int rc;
    101 
    102         /* Connect to a program loader. */
    103         ldr = loader_connect();
    104         if (ldr == NULL)
    105                 return EREFUSED;
    106        
    107         /* Get task ID. */
    108         rc = loader_get_task_id(ldr, &task_id);
    109         if (rc != EOK)
    110                 goto error;
    111        
    112         /* Send spawner's current working directory. */
    113         rc = loader_set_cwd(ldr);
    114         if (rc != EOK)
    115                 goto error;
    116        
    117         /* Send program pathname. */
    118         rc = loader_set_pathname(ldr, path);
    119         if (rc != EOK)
    120                 goto error;
    121        
    122         /* Send arguments. */
    123         rc = loader_set_args(ldr, args);
    124         if (rc != EOK)
    125                 goto error;
    126        
    127103        /* Send default files */
    128104        fdi_node_t *files[4];
     
    148124        files[3] = NULL;
    149125       
     126        return task_spawnvf(id, path, args, files);
     127}
     128
     129/** Create a new task by running an executable from the filesystem.
     130 *
     131 * This is really just a convenience wrapper over the more complicated
     132 * loader API. Arguments are passed as a null-terminated array of strings.
     133 * Files are passed as null-terminated array of pointers to fdi_node_t.
     134 *
     135 * @param id    If not NULL, the ID of the task is stored here on success.
     136 * @param path  Pathname of the binary to execute.
     137 * @param argv  Command-line arguments.
     138 * @param files Standard files to use.
     139 *
     140 * @return Zero on success or negative error code.
     141 *
     142 */
     143int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
     144    fdi_node_t *const files[])
     145{
     146        /* Connect to a program loader. */
     147        loader_t *ldr = loader_connect();
     148        if (ldr == NULL)
     149                return EREFUSED;
     150       
     151        /* Get task ID. */
     152        task_id_t task_id;
     153        int rc = loader_get_task_id(ldr, &task_id);
     154        if (rc != EOK)
     155                goto error;
     156       
     157        /* Send spawner's current working directory. */
     158        rc = loader_set_cwd(ldr);
     159        if (rc != EOK)
     160                goto error;
     161       
     162        /* Send program pathname. */
     163        rc = loader_set_pathname(ldr, path);
     164        if (rc != EOK)
     165                goto error;
     166       
     167        /* Send arguments. */
     168        rc = loader_set_args(ldr, args);
     169        if (rc != EOK)
     170                goto error;
     171       
     172        /* Send files */
    150173        rc = loader_set_files(ldr, files);
    151174        if (rc != EOK)
     
    163186       
    164187        /* Success */
    165         free(ldr);
    166        
    167188        if (id != NULL)
    168189                *id = task_id;
     
    173194        /* Error exit */
    174195        loader_abort(ldr);
    175         free(ldr);
    176196        return rc;
    177197}
     
    182202 * loader API. Arguments are passed as a null-terminated list of arguments.
    183203 *
    184  * @param id    If not NULL, the ID of the task is stored here on success.
    185  * @param path  Pathname of the binary to execute.
    186  * @param ...   Command-line arguments.
    187  *
    188  * @return      Zero on success or negative error code.
     204 * @param id   If not NULL, the ID of the task is stored here on success.
     205 * @param path Pathname of the binary to execute.
     206 * @param ...  Command-line arguments.
     207 *
     208 * @return Zero on success or negative error code.
     209 *
    189210 */
    190211int task_spawnl(task_id_t *task_id, const char *path, ...)
    191212{
     213        /* Count the number of arguments. */
     214       
    192215        va_list ap;
    193         int rc, cnt;
    194216        const char *arg;
    195217        const char **arglist;
    196 
    197         /* Count the number of arguments. */
    198         cnt = 0;
     218        int cnt = 0;
     219       
    199220        va_start(ap, path);
    200221        do {
     
    203224        } while (arg != NULL);
    204225        va_end(ap);
    205 
     226       
    206227        /* Allocate argument list. */
    207228        arglist = malloc(cnt * sizeof(const char *));
    208229        if (arglist == NULL)
    209230                return ENOMEM;
    210 
     231       
    211232        /* Fill in arguments. */
    212233        cnt = 0;
     
    217238        } while (arg != NULL);
    218239        va_end(ap);
    219 
     240       
    220241        /* Spawn task. */
    221         rc = task_spawnv(task_id, path, arglist);
    222 
     242        int rc = task_spawnv(task_id, path, arglist);
     243       
    223244        /* Free argument list. */
    224245        free(arglist);
     
    228249int task_wait(task_id_t id, task_exit_t *texit, int *retval)
    229250{
     251        assert(texit);
     252        assert(retval);
     253       
     254        async_exch_t *exch = async_exchange_begin(session_ns);
    230255        sysarg_t te, rv;
    231         int rc;
    232 
    233         rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
     256        int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id),
    234257            UPPER32(id), &te, &rv);
     258        async_exchange_end(exch);
     259       
    235260        *texit = te;
    236261        *retval = rv;
    237 
     262       
    238263        return rc;
    239264}
     
    241266int task_retval(int val)
    242267{
    243         return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
     268        async_exch_t *exch = async_exchange_begin(session_ns);
     269        int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
     270        async_exchange_end(exch);
     271       
     272        return rc;
    244273}
    245274
  • uspace/lib/c/generic/thread.c

    r52a79081 ra33f0a6  
    4444
    4545#ifndef THREAD_INITIAL_STACK_PAGES_NO
    46 #define THREAD_INITIAL_STACK_PAGES_NO 1
     46#define THREAD_INITIAL_STACK_PAGES_NO   2
    4747#endif
    4848
  • uspace/lib/c/generic/time.c

    r52a79081 ra33f0a6  
    207207}
    208208
     209void udelay(useconds_t time)
     210{
     211        (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
     212}
     213
     214
    209215/** Wait unconditionally for specified number of seconds
    210216 *
  • uspace/lib/c/generic/udebug.c

    r52a79081 ra33f0a6  
    3535#include <udebug.h>
    3636#include <sys/types.h>
     37#include <kernel/ipc/ipc_methods.h>
    3738#include <async.h>
    3839
    39 int udebug_begin(int phoneid)
     40int udebug_begin(async_sess_t *sess)
    4041{
    41         return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN);
     42        async_exch_t *exch = async_exchange_begin(sess);
     43        return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN);
    4244}
    4345
    44 int udebug_end(int phoneid)
     46int udebug_end(async_sess_t *sess)
    4547{
    46         return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_END);
     48        async_exch_t *exch = async_exchange_begin(sess);
     49        return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END);
    4750}
    4851
    49 int udebug_set_evmask(int phoneid, udebug_evmask_t mask)
     52int udebug_set_evmask(async_sess_t *sess, udebug_evmask_t mask)
    5053{
    51         return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_SET_EVMASK,
    52                 mask);
     54        async_exch_t *exch = async_exchange_begin(sess);
     55        return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask);
    5356}
    5457
    55 int udebug_thread_read(int phoneid, void *buffer, size_t n,
    56         size_t *copied, size_t *needed)
     58int udebug_thread_read(async_sess_t *sess, void *buffer, size_t n,
     59    size_t *copied, size_t *needed)
    5760{
    5861        sysarg_t a_copied, a_needed;
    59         int rc;
    60 
    61         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
    62                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    63 
    64         *copied = (size_t)a_copied;
    65         *needed = (size_t)a_needed;
    66 
     62       
     63        async_exch_t *exch = async_exchange_begin(sess);
     64        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ,
     65            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     66       
     67        *copied = (size_t) a_copied;
     68        *needed = (size_t) a_needed;
     69       
    6770        return rc;
    6871}
    6972
    70 int udebug_name_read(int phoneid, void *buffer, size_t n,
    71         size_t *copied, size_t *needed)
     73int udebug_name_read(async_sess_t *sess, void *buffer, size_t n,
     74    size_t *copied, size_t *needed)
    7275{
    7376        sysarg_t a_copied, a_needed;
    74         int rc;
    75 
    76         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
    77                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    78 
    79         *copied = (size_t)a_copied;
    80         *needed = (size_t)a_needed;
    81 
     77       
     78        async_exch_t *exch = async_exchange_begin(sess);
     79        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ,
     80            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     81       
     82        *copied = (size_t) a_copied;
     83        *needed = (size_t) a_needed;
     84       
    8285        return rc;
    8386}
    8487
    85 int udebug_areas_read(int phoneid, void *buffer, size_t n,
    86         size_t *copied, size_t *needed)
     88int udebug_areas_read(async_sess_t *sess, void *buffer, size_t n,
     89    size_t *copied, size_t *needed)
    8790{
    8891        sysarg_t a_copied, a_needed;
    89         int rc;
    90 
    91         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,
    92                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    93 
    94         *copied = (size_t)a_copied;
    95         *needed = (size_t)a_needed;
    96 
     92       
     93        async_exch_t *exch = async_exchange_begin(sess);
     94        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ,
     95            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     96       
     97        *copied = (size_t) a_copied;
     98        *needed = (size_t) a_needed;
     99       
    97100        return rc;
    98101}
    99102
    100 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
     103int udebug_mem_read(async_sess_t *sess, void *buffer, uintptr_t addr, size_t n)
    101104{
    102         return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ,
    103             (sysarg_t)buffer, addr, n);
     105        async_exch_t *exch = async_exchange_begin(sess);
     106        return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ,
     107            (sysarg_t) buffer, addr, n);
    104108}
    105109
    106 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer)
     110int udebug_args_read(async_sess_t *sess, thash_t tid, sysarg_t *buffer)
    107111{
    108         return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
    109             tid, (sysarg_t)buffer);
     112        async_exch_t *exch = async_exchange_begin(sess);
     113        return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ,
     114            tid, (sysarg_t) buffer);
    110115}
    111116
    112 int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
     117int udebug_regs_read(async_sess_t *sess, thash_t tid, void *buffer)
    113118{
    114         return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
    115             tid, (sysarg_t)buffer);
     119        async_exch_t *exch = async_exchange_begin(sess);
     120        return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ,
     121            tid, (sysarg_t) buffer);
    116122}
    117123
    118 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
     124int udebug_go(async_sess_t *sess, thash_t tid, udebug_event_t *ev_type,
    119125    sysarg_t *val0, sysarg_t *val1)
    120126{
    121127        sysarg_t a_ev_type;
    122         int rc;
    123 
    124         rc =  async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
     128       
     129        async_exch_t *exch = async_exchange_begin(sess);
     130        int rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO,
    125131            tid, &a_ev_type, val0, val1);
    126 
     132       
    127133        *ev_type = a_ev_type;
    128134        return rc;
    129135}
    130136
    131 int udebug_stop(int phoneid, thash_t tid)
     137int udebug_stop(async_sess_t *sess, thash_t tid)
    132138{
    133         return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_STOP,
    134             tid);
     139        async_exch_t *exch = async_exchange_begin(sess);
     140        return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid);
    135141}
    136142
  • uspace/lib/c/generic/vfs/vfs.c

    r52a79081 ra33f0a6  
    3333 */
    3434
     35#include <vfs/canonify.h>
    3536#include <vfs/vfs.h>
    36 #include <vfs/canonify.h>
     37#include <vfs/vfs_sess.h>
    3738#include <macros.h>
    3839#include <stdlib.h>
     
    4445#include <sys/types.h>
    4546#include <ipc/services.h>
    46 #include <ipc/ns.h>
     47#include <ns.h>
    4748#include <async.h>
    4849#include <fibril_synch.h>
     
    5455#include <ipc/devmap.h>
    5556
    56 static async_sess_t vfs_session;
    57 
    58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    59 static int vfs_phone = -1;
     57static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
     58static async_sess_t *vfs_sess = NULL;
    6059
    6160static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     
    6564static size_t cwd_size = 0;
    6665
     66/** Start an async exchange on the VFS session.
     67 *
     68 * @return New exchange.
     69 *
     70 */
     71static async_exch_t *vfs_exchange_begin(void)
     72{
     73        fibril_mutex_lock(&vfs_mutex);
     74       
     75        while (vfs_sess == NULL)
     76                vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS,
     77                    0, 0);
     78       
     79        fibril_mutex_unlock(&vfs_mutex);
     80       
     81        return async_exchange_begin(vfs_sess);
     82}
     83
     84/** Finish an async exchange on the VFS session.
     85 *
     86 * @param exch Exchange to be finished.
     87 *
     88 */
     89static void vfs_exchange_end(async_exch_t *exch)
     90{
     91        async_exchange_end(exch);
     92}
     93
    6794char *absolutize(const char *path, size_t *retlen)
    6895{
    6996        char *ncwd_path;
    7097        char *ncwd_path_nc;
    71         size_t total_size;
    7298
    7399        fibril_mutex_lock(&cwd_mutex);
     
    78104                        return NULL;
    79105                }
    80                 total_size = cwd_size + 1 + size + 1;
    81                 ncwd_path_nc = malloc(total_size);
     106                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    82107                if (!ncwd_path_nc) {
    83108                        fibril_mutex_unlock(&cwd_mutex);
    84109                        return NULL;
    85110                }
    86                 str_cpy(ncwd_path_nc, total_size, cwd_path);
     111                str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
    87112                ncwd_path_nc[cwd_size] = '/';
    88113                ncwd_path_nc[cwd_size + 1] = '\0';
    89114        } else {
    90                 total_size = size + 1;
    91                 ncwd_path_nc = malloc(total_size);
     115                ncwd_path_nc = malloc(size + 1);
    92116                if (!ncwd_path_nc) {
    93117                        fibril_mutex_unlock(&cwd_mutex);
     
    96120                ncwd_path_nc[0] = '\0';
    97121        }
    98         str_append(ncwd_path_nc, total_size, path);
     122        str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
    99123        ncwd_path = canonify(ncwd_path_nc, retlen);
    100124        if (!ncwd_path) {
     
    118142}
    119143
    120 /** Connect to VFS service and create session. */
    121 static void vfs_connect(void)
    122 {
    123         while (vfs_phone < 0)
    124                 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    125        
    126         async_session_create(&vfs_session, vfs_phone, 0);
    127 }
    128 
    129 /** Start an async exchange on the VFS session.
    130  *
    131  * @return              New phone to be used during the exchange.
    132  */
    133 static int vfs_exchange_begin(void)
    134 {
    135         fibril_mutex_lock(&vfs_phone_mutex);
    136         if (vfs_phone < 0)
    137                 vfs_connect();
    138         fibril_mutex_unlock(&vfs_phone_mutex);
    139 
    140         return async_exchange_begin(&vfs_session);
    141 }
    142 
    143 /** End an async exchange on the VFS session.
    144  *
    145  * @param phone         Phone used during the exchange.
    146  */
    147 static void vfs_exchange_end(int phone)
    148 {
    149         async_exchange_end(&vfs_session, phone);
    150 }
    151 
    152144int mount(const char *fs_name, const char *mp, const char *fqdn,
    153145    const char *opts, unsigned int flags)
     
    186178        }
    187179       
    188         int vfs_phone = vfs_exchange_begin();
     180        async_exch_t *exch = vfs_exchange_begin();
    189181
    190182        sysarg_t rc_orig;
    191         aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    192         sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    193         if (rc != EOK) {
    194                 vfs_exchange_end(vfs_phone);
     183        aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);
     184        sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     185        if (rc != EOK) {
     186                vfs_exchange_end(exch);
    195187                free(mpa);
    196188                async_wait_for(req, &rc_orig);
     
    205197        }
    206198       
    207         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    208         if (rc != EOK) {
    209                 vfs_exchange_end(vfs_phone);
     199        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     200        if (rc != EOK) {
     201                vfs_exchange_end(exch);
    210202                free(mpa);
    211203                async_wait_for(req, &rc_orig);
     
    220212        }
    221213       
    222         rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    223         if (rc != EOK) {
    224                 vfs_exchange_end(vfs_phone);
     214        rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
     215        if (rc != EOK) {
     216                vfs_exchange_end(exch);
    225217                free(mpa);
    226218                async_wait_for(req, &rc_orig);
     
    236228       
    237229        /* Ask VFS whether it likes fs_name. */
    238         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    239         if (rc != EOK) {
    240                 vfs_exchange_end(vfs_phone);
     230        rc = async_req_0_0(exch, VFS_IN_PING);
     231        if (rc != EOK) {
     232                vfs_exchange_end(exch);
    241233                free(mpa);
    242234                async_wait_for(req, &rc_orig);
     
    251243        }
    252244       
    253         vfs_exchange_end(vfs_phone);
     245        vfs_exchange_end(exch);
    254246        free(mpa);
    255247        async_wait_for(req, &rc);
     
    273265                return ENOMEM;
    274266       
    275         int vfs_phone = vfs_exchange_begin();
    276        
    277         req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    278         rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    279         if (rc != EOK) {
    280                 vfs_exchange_end(vfs_phone);
     267        async_exch_t *exch = vfs_exchange_begin();
     268       
     269        req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
     270        rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     271        if (rc != EOK) {
     272                vfs_exchange_end(exch);
    281273                free(mpa);
    282274                async_wait_for(req, &rc_orig);
     
    288280       
    289281
    290         vfs_exchange_end(vfs_phone);
     282        vfs_exchange_end(exch);
    291283        free(mpa);
    292284        async_wait_for(req, &rc);
     
    297289static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    298290{
    299         int vfs_phone = vfs_exchange_begin();
     291        async_exch_t *exch = vfs_exchange_begin();
    300292       
    301293        ipc_call_t answer;
    302         aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
    303         sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
    304        
    305         if (rc != EOK) {
    306                 vfs_exchange_end(vfs_phone);
     294        aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     295        sysarg_t rc = async_data_write_start(exch, abs, abs_size);
     296       
     297        if (rc != EOK) {
     298                vfs_exchange_end(exch);
    307299
    308300                sysarg_t rc_orig;
     
    315307        }
    316308       
    317         vfs_exchange_end(vfs_phone);
     309        vfs_exchange_end(exch);
    318310        async_wait_for(req, &rc);
    319311       
     
    339331int open_node(fdi_node_t *node, int oflag)
    340332{
    341         int vfs_phone = vfs_exchange_begin();
     333        async_exch_t *exch = vfs_exchange_begin();
    342334       
    343335        ipc_call_t answer;
    344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
     336        aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
    345337            node->devmap_handle, node->index, oflag, &answer);
    346338       
    347         vfs_exchange_end(vfs_phone);
     339        vfs_exchange_end(exch);
    348340
    349341        sysarg_t rc;
     
    360352        sysarg_t rc;
    361353       
    362         int vfs_phone = vfs_exchange_begin();
    363        
    364         rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    365        
    366         vfs_exchange_end(vfs_phone);
    367        
    368         return (int)rc;
     354        async_exch_t *exch = vfs_exchange_begin();
     355        rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
     356        vfs_exchange_end(exch);
     357       
     358        return (int) rc;
    369359}
    370360
     
    374364        ipc_call_t answer;
    375365        aid_t req;
    376 
    377         int vfs_phone = vfs_exchange_begin();
    378        
    379         req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    380         rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
    381             IPC_XF_RESTRICT);
    382         if (rc != EOK) {
    383                 vfs_exchange_end(vfs_phone);
     366       
     367        async_exch_t *exch = vfs_exchange_begin();
     368       
     369        req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
     370        rc = async_data_read_start(exch, (void *)buf, nbyte);
     371        if (rc != EOK) {
     372                vfs_exchange_end(exch);
    384373
    385374                sysarg_t rc_orig;
     
    391380                        return (ssize_t) rc_orig;
    392381        }
    393         vfs_exchange_end(vfs_phone);
     382        vfs_exchange_end(exch);
    394383        async_wait_for(req, &rc);
    395384        if (rc == EOK)
     
    404393        ipc_call_t answer;
    405394        aid_t req;
    406 
    407         int vfs_phone = vfs_exchange_begin();
    408        
    409         req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    410         rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
    411             IPC_XF_RESTRICT);
    412         if (rc != EOK) {
    413                 vfs_exchange_end(vfs_phone);
     395       
     396        async_exch_t *exch = vfs_exchange_begin();
     397       
     398        req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
     399        rc = async_data_write_start(exch, (void *)buf, nbyte);
     400        if (rc != EOK) {
     401                vfs_exchange_end(exch);
    414402
    415403                sysarg_t rc_orig;
     
    421409                        return (ssize_t) rc_orig;
    422410        }
    423         vfs_exchange_end(vfs_phone);
     411        vfs_exchange_end(exch);
    424412        async_wait_for(req, &rc);
    425413        if (rc == EOK)
     
    429417}
    430418
     419/** Read entire buffer.
     420 *
     421 * In face of short reads this function continues reading until either
     422 * the entire buffer is read or no more data is available (at end of file).
     423 *
     424 * @param fildes        File descriptor
     425 * @param buf           Buffer, @a nbytes bytes long
     426 * @param nbytes        Number of bytes to read
     427 *
     428 * @return              On success, positive number of bytes read.
     429 *                      On failure, negative error code from read().
     430 */
     431ssize_t read_all(int fildes, void *buf, size_t nbyte)
     432{
     433        ssize_t cnt = 0;
     434        size_t nread = 0;
     435        uint8_t *bp = (uint8_t *) buf;
     436
     437        do {
     438                bp += cnt;
     439                nread += cnt;
     440                cnt = read(fildes, bp, nbyte - nread);
     441        } while (cnt > 0 && (nbyte - nread - cnt) > 0);
     442
     443        if (cnt < 0)
     444                return cnt;
     445
     446        return nread + cnt;
     447}
     448
     449/** Write entire buffer.
     450 *
     451 * This function fails if it cannot write exactly @a len bytes to the file.
     452 *
     453 * @param fildes        File descriptor
     454 * @param buf           Data, @a nbytes bytes long
     455 * @param nbytes        Number of bytes to write
     456 *
     457 * @return              EOK on error, return value from write() if writing
     458 *                      failed.
     459 */
     460ssize_t write_all(int fildes, const void *buf, size_t nbyte)
     461{
     462        ssize_t cnt = 0;
     463        ssize_t nwritten = 0;
     464        const uint8_t *bp = (uint8_t *) buf;
     465
     466        do {
     467                bp += cnt;
     468                nwritten += cnt;
     469                cnt = write(fildes, bp, nbyte - nwritten);
     470        } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
     471
     472        if (cnt < 0)
     473                return cnt;
     474
     475        if ((ssize_t)nbyte - nwritten - cnt > 0)
     476                return EIO;
     477
     478        return nbyte;
     479}
     480
    431481int fsync(int fildes)
    432482{
    433         int vfs_phone = vfs_exchange_begin();
    434        
    435         sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    436        
    437         vfs_exchange_end(vfs_phone);
     483        async_exch_t *exch = vfs_exchange_begin();
     484        sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
     485        vfs_exchange_end(exch);
    438486       
    439487        return (int) rc;
     
    442490off64_t lseek(int fildes, off64_t offset, int whence)
    443491{
    444         int vfs_phone = vfs_exchange_begin();
     492        async_exch_t *exch = vfs_exchange_begin();
    445493       
    446494        sysarg_t newoff_lo;
    447495        sysarg_t newoff_hi;
    448         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     496        sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
    449497            LOWER32(offset), UPPER32(offset), whence,
    450498            &newoff_lo, &newoff_hi);
    451499       
    452         vfs_exchange_end(vfs_phone);
     500        vfs_exchange_end(exch);
    453501       
    454502        if (rc != EOK)
     
    462510        sysarg_t rc;
    463511       
    464         int vfs_phone = vfs_exchange_begin();
    465        
    466         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     512        async_exch_t *exch = vfs_exchange_begin();
     513        rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
    467514            LOWER32(length), UPPER32(length));
    468         vfs_exchange_end(vfs_phone);
     515        vfs_exchange_end(exch);
    469516       
    470517        return (int) rc;
     
    475522        sysarg_t rc;
    476523        aid_t req;
    477 
    478         int vfs_phone = vfs_exchange_begin();
    479        
    480         req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481         rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482         if (rc != EOK) {
    483                 vfs_exchange_end(vfs_phone);
     524       
     525        async_exch_t *exch = vfs_exchange_begin();
     526       
     527        req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
     528        rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
     529        if (rc != EOK) {
     530                vfs_exchange_end(exch);
    484531
    485532                sysarg_t rc_orig;
     
    491538                        return (ssize_t) rc_orig;
    492539        }
    493         vfs_exchange_end(vfs_phone);
     540        vfs_exchange_end(exch);
    494541        async_wait_for(req, &rc);
    495542
     
    508555                return ENOMEM;
    509556       
    510         int vfs_phone = vfs_exchange_begin();
    511        
    512         req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    513         rc = async_data_write_start(vfs_phone, pa, pa_size);
    514         if (rc != EOK) {
    515                 vfs_exchange_end(vfs_phone);
     557        async_exch_t *exch = vfs_exchange_begin();
     558       
     559        req = async_send_0(exch, VFS_IN_STAT, NULL);
     560        rc = async_data_write_start(exch, pa, pa_size);
     561        if (rc != EOK) {
     562                vfs_exchange_end(exch);
    516563                free(pa);
    517564                async_wait_for(req, &rc_orig);
     
    521568                        return (int) rc_orig;
    522569        }
    523         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    524         if (rc != EOK) {
    525                 vfs_exchange_end(vfs_phone);
     570        rc = async_data_read_start(exch, stat, sizeof(struct stat));
     571        if (rc != EOK) {
     572                vfs_exchange_end(exch);
    526573                free(pa);
    527574                async_wait_for(req, &rc_orig);
     
    531578                        return (int) rc_orig;
    532579        }
    533         vfs_exchange_end(vfs_phone);
     580        vfs_exchange_end(exch);
    534581        free(pa);
    535582        async_wait_for(req, &rc);
     
    592639                return ENOMEM;
    593640       
    594         int vfs_phone = vfs_exchange_begin();
    595        
    596         req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    597         rc = async_data_write_start(vfs_phone, pa, pa_size);
    598         if (rc != EOK) {
    599                 vfs_exchange_end(vfs_phone);
     641        async_exch_t *exch = vfs_exchange_begin();
     642       
     643        req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
     644        rc = async_data_write_start(exch, pa, pa_size);
     645        if (rc != EOK) {
     646                vfs_exchange_end(exch);
    600647                free(pa);
    601648
     
    608655                        return (int) rc_orig;
    609656        }
    610         vfs_exchange_end(vfs_phone);
     657        vfs_exchange_end(exch);
    611658        free(pa);
    612659        async_wait_for(req, &rc);
     
    623670        if (!pa)
    624671                return ENOMEM;
    625 
    626         int vfs_phone = vfs_exchange_begin();
    627        
    628         req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    629         rc = async_data_write_start(vfs_phone, pa, pa_size);
    630         if (rc != EOK) {
    631                 vfs_exchange_end(vfs_phone);
     672       
     673        async_exch_t *exch = vfs_exchange_begin();
     674       
     675        req = async_send_0(exch, VFS_IN_UNLINK, NULL);
     676        rc = async_data_write_start(exch, pa, pa_size);
     677        if (rc != EOK) {
     678                vfs_exchange_end(exch);
    632679                free(pa);
    633680
     
    640687                        return (int) rc_orig;
    641688        }
    642         vfs_exchange_end(vfs_phone);
     689        vfs_exchange_end(exch);
    643690        free(pa);
    644691        async_wait_for(req, &rc);
     
    673720                return ENOMEM;
    674721        }
    675 
    676         int vfs_phone = vfs_exchange_begin();
    677        
    678         req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    679         rc = async_data_write_start(vfs_phone, olda, olda_size);
    680         if (rc != EOK) {
    681                 vfs_exchange_end(vfs_phone);
     722       
     723        async_exch_t *exch = vfs_exchange_begin();
     724       
     725        req = async_send_0(exch, VFS_IN_RENAME, NULL);
     726        rc = async_data_write_start(exch, olda, olda_size);
     727        if (rc != EOK) {
     728                vfs_exchange_end(exch);
    682729                free(olda);
    683730                free(newa);
     
    688735                        return (int) rc_orig;
    689736        }
    690         rc = async_data_write_start(vfs_phone, newa, newa_size);
    691         if (rc != EOK) {
    692                 vfs_exchange_end(vfs_phone);
     737        rc = async_data_write_start(exch, newa, newa_size);
     738        if (rc != EOK) {
     739                vfs_exchange_end(exch);
    693740                free(olda);
    694741                free(newa);
     
    699746                        return (int) rc_orig;
    700747        }
    701         vfs_exchange_end(vfs_phone);
     748        vfs_exchange_end(exch);
    702749        free(olda);
    703750        free(newa);
     
    755802}
    756803
    757 int fd_phone(int fildes)
     804async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
    758805{
    759806        struct stat stat;
    760        
    761807        int rc = fstat(fildes, &stat);
    762         if (rc != 0)
    763                 return rc;
    764        
    765         if (!stat.device)
    766                 return -1;
    767        
    768         return devmap_device_connect(stat.device, 0);
     808        if (rc != 0) {
     809                errno = rc;
     810                return NULL;
     811        }
     812       
     813        if (!stat.device) {
     814                errno = ENOENT;
     815                return NULL;
     816        }
     817       
     818        return devmap_device_connect(mgmt, stat.device, 0);
    769819}
    770820
     
    772822{
    773823        struct stat stat;
    774         int rc;
    775 
    776         rc = fstat(fildes, &stat);
     824        int rc = fstat(fildes, &stat);
    777825       
    778826        if (rc == EOK) {
     
    787835int dup2(int oldfd, int newfd)
    788836{
    789         int vfs_phone = vfs_exchange_begin();
     837        async_exch_t *exch = vfs_exchange_begin();
    790838       
    791839        sysarg_t ret;
    792         sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    793        
    794         vfs_exchange_end(vfs_phone);
     840        sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
     841       
     842        vfs_exchange_end(exch);
    795843       
    796844        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.