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


Ignore:
Timestamp:
2011-11-06T22:21:05Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
Children:
898e847
Parents:
2bdf8313 (diff), 7b5f4c9 (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 mainline changes.

Location:
uspace/lib/c/generic
Files:
8 added
4 deleted
43 edited
3 moved

Legend:

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

    r2bdf8313 rb0f00a9  
    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;
     
    7878}
    7979
     80/** Remove all elements from the hash table
     81 *
     82 * @param h Hash table to be cleared
     83 */
     84void hash_table_clear(hash_table_t *h)
     85{
     86        for (hash_count_t chain = 0; chain < h->entries; ++chain) {
     87                link_t *cur;
     88                link_t *next;
     89               
     90                for (cur = h->entry[chain].head.next;
     91                    cur != &h->entry[chain].head;
     92                    cur = next) {
     93                        next = cur->next;
     94                        list_remove(cur);
     95                        h->op->remove_callback(cur);
     96                }
     97        }
     98}
     99
    80100/** Destroy a hash table instance.
    81101 *
     
    123143        assert(chain < h->entries);
    124144       
    125         link_t *cur;
    126         for (cur = h->entry[chain].next; cur != &h->entry[chain];
    127             cur = cur->next) {
     145        list_foreach(h->entry[chain], cur) {
    128146                if (h->op->compare(key, h->max_keys, cur)) {
    129147                        /*
     
    152170            h->op->remove_callback);
    153171        assert(keys <= h->max_keys);
    154        
    155         link_t *cur;
    156172       
    157173        if (keys == h->max_keys) {
     
    161177                 */
    162178               
    163                 cur = hash_table_find(h, key);
     179                link_t *cur = hash_table_find(h, key);
    164180                if (cur) {
    165181                        list_remove(cur);
     
    176192        hash_index_t chain;
    177193        for (chain = 0; chain < h->entries; chain++) {
    178                 for (cur = h->entry[chain].next; cur != &h->entry[chain];
     194                for (link_t *cur = h->entry[chain].head.next;
     195                    cur != &h->entry[chain].head;
    179196                    cur = cur->next) {
    180197                        if (h->op->compare(key, keys, cur)) {
     
    193210}
    194211
    195 /** Apply fucntion to all items in hash table.
     212/** Apply function to all items in hash table.
    196213 *
    197214 * @param h   Hash table.
     
    201218 */
    202219void hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
    203 {
    204         hash_index_t bucket;
    205         link_t *cur;
    206        
    207         for (bucket = 0; bucket < h->entries; bucket++) {
    208                 for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
    209                     cur = cur->next) {
     220{       
     221        for (hash_index_t bucket = 0; bucket < h->entries; bucket++) {
     222                link_t *cur;
     223                link_t *next;
     224
     225                for (cur = h->entry[bucket].head.next; cur != &h->entry[bucket].head;
     226                    cur = next) {
     227                        /*
     228                         * The next pointer must be stored prior to the functor
     229                         * call to allow using destructor as the functor (the
     230                         * free function could overwrite the cur->next pointer).
     231                         */
     232                        next = cur->next;
    210233                        f(cur, arg);
    211234                }
  • uspace/lib/c/generic/adt/list.c

    r2bdf8313 rb0f00a9  
    3030 * @{
    3131 */
    32 /** @file
     32
     33/**
     34 * @file
     35 * @brief       Functions completing doubly linked circular list implementation.
     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 *
    46  * @return true if link is contained in head, false otherwise.
     52 * @return true if link is contained in list, 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

    r2bdf8313 rb0f00a9  
    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/adt/prodcons.c

    r2bdf8313 rb0f00a9  
    6161                fibril_condvar_wait(&pc->cv, &pc->mtx);
    6262       
    63         link_t *head = pc->list.next;
     63        link_t *head = list_first(&pc->list);
    6464        list_remove(head);
    6565       
  • uspace/lib/c/generic/as.c

    r2bdf8313 rb0f00a9  
    3535#include <as.h>
    3636#include <libc.h>
     37#include <errno.h>
    3738#include <unistd.h>
    3839#include <align.h>
     
    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(const 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

    r2bdf8313 rb0f00a9  
    3737#include <atomic.h>
    3838#include <stacktrace.h>
     39#include <stdint.h>
    3940
    40 #define MSG_START       "Assertion failed ("
    41 #define MSG_FILE        ") in file \""
    42 #define MSG_LINE        "\", line "
    43 #define MSG_END         ".\n"
     41static atomic_t failed_asserts = {0};
    4442
    45 static atomic_t failed_asserts;
    46 
    47 void assert_abort(const char *cond, const char *file, const char *line)
     43void assert_abort(const char *cond, const char *file, unsigned int line)
    4844{
    4945        /*
    5046         * Send the message safely to klog. Nested asserts should not occur.
    5147         */
    52         klog_write(MSG_START, str_size(MSG_START));
    53         klog_write(cond, str_size(cond));
    54         klog_write(MSG_FILE, str_size(MSG_FILE));
    55         klog_write(file, str_size(file));
    56         klog_write(MSG_LINE, str_size(MSG_LINE));
    57         klog_write(line, str_size(line));
    58         klog_write(MSG_END, str_size(MSG_END));
    59 
     48        klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
     49            cond, file, line);
     50       
    6051        /*
    6152         * Check if this is a nested or parallel assert.
     
    6960         * assertions.
    7061         */
    71         printf(MSG_START "%s" MSG_FILE "%s" MSG_LINE "%s" MSG_END,
     62        printf("Assertion failed (%s) in file \"%s\", line %u.\n",
    7263            cond, file, line);
    7364        stacktrace_print();
    74 
     65       
    7566        abort();
    7667}
  • uspace/lib/c/generic/async.c

    r2bdf8313 rb0f00a9  
    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);
     
    9098#include <ipc/ipc.h>
    9199#include <async.h>
     100#include "private/async.h"
    92101#undef LIBC_ASYNC_C_
    93102
    94103#include <futex.h>
    95104#include <fibril.h>
    96 #include <stdio.h>
    97105#include <adt/hash_table.h>
    98106#include <adt/list.h>
     
    100108#include <errno.h>
    101109#include <sys/time.h>
    102 #include <arch/barrier.h>
     110#include <libarch/barrier.h>
    103111#include <bool.h>
     112#include <malloc.h>
     113#include <mem.h>
    104114#include <stdlib.h>
    105 #include <malloc.h>
    106 #include "private/async.h"
    107 
     115#include <macros.h>
     116
     117#define CLIENT_HASH_TABLE_BUCKETS  32
     118#define CONN_HASH_TABLE_BUCKETS    32
     119
     120/** Session data */
     121struct async_sess {
     122        /** List of inactive exchanges */
     123        list_t exch_list;
     124       
     125        /** Exchange management style */
     126        exch_mgmt_t mgmt;
     127       
     128        /** Session identification */
     129        int phone;
     130       
     131        /** First clone connection argument */
     132        sysarg_t arg1;
     133       
     134        /** Second clone connection argument */
     135        sysarg_t arg2;
     136       
     137        /** Third clone connection argument */
     138        sysarg_t arg3;
     139       
     140        /** Exchange mutex */
     141        fibril_mutex_t mutex;
     142       
     143        /** Number of opened exchanges */
     144        atomic_t refcnt;
     145       
     146        /** Mutex for stateful connections */
     147        fibril_mutex_t remote_state_mtx;
     148       
     149        /** Data for stateful connections */
     150        void *remote_state_data;
     151};
     152
     153/** Exchange data */
     154struct async_exch {
     155        /** Link into list of inactive exchanges */
     156        link_t sess_link;
     157       
     158        /** Link into global list of inactive exchanges */
     159        link_t global_link;
     160       
     161        /** Session pointer */
     162        async_sess_t *sess;
     163       
     164        /** Exchange identification */
     165        int phone;
     166};
     167
     168/** Async framework global futex */
    108169atomic_t async_futex = FUTEX_INITIALIZER;
    109170
     
    111172atomic_t threads_in_ipc_wait = { 0 };
    112173
    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  */
     174/** Naming service session */
     175async_sess_t *session_ns;
     176
     177/** Call data */
    129178typedef struct {
    130179        link_t link;
     180       
    131181        ipc_callid_t callid;
    132182        ipc_call_t call;
    133183} msg_t;
    134184
     185/** Message data */
    135186typedef struct {
    136         sysarg_t in_task_hash;
     187        awaiter_t wdata;
     188       
     189        /** If reply was received. */
     190        bool done;
     191       
     192        /** Pointer to where the answer data is stored. */
     193        ipc_call_t *dataptr;
     194       
     195        sysarg_t retval;
     196} amsg_t;
     197
     198/* Client connection data */
     199typedef struct {
    137200        link_t link;
    138         int refcnt;
     201       
     202        task_id_t in_task_id;
     203        atomic_t refcnt;
    139204        void *data;
    140205} client_t;
    141206
     207/* Server connection data */
    142208typedef struct {
    143209        awaiter_t wdata;
     
    146212        link_t link;
    147213       
    148         /** Incoming client task hash. */
    149         sysarg_t in_task_hash;
     214        /** Incoming client task ID. */
     215        task_id_t in_task_id;
     216       
    150217        /** Incoming phone hash. */
    151218        sysarg_t in_phone_hash;
     
    155222       
    156223        /** Messages that should be delivered to this fibril. */
    157         link_t msg_queue;
     224        list_t msg_queue;
    158225       
    159226        /** Identification of the opening call. */
     
    161228        /** Call data of the opening call. */
    162229        ipc_call_t call;
     230        /** Local argument or NULL if none. */
     231        void *carg;
    163232       
    164233        /** Identification of the closing call. */
     
    166235       
    167236        /** Fibril function that will be used to handle the connection. */
    168         void (*cfibril)(ipc_callid_t, ipc_call_t *);
     237        async_client_conn_t cfibril;
    169238} connection_t;
    170239
    171240/** Identifier of the incoming connection handled by the current fibril. */
    172 static fibril_local connection_t *FIBRIL_connection;
     241static fibril_local connection_t *fibril_connection;
    173242
    174243static void *default_client_data_constructor(void)
     
    196265}
    197266
    198 void *async_client_data_get(void)
    199 {
    200         assert(FIBRIL_connection);
    201         return FIBRIL_connection->client->data;
    202 }
    203 
    204267/** Default fibril function that gets called to handle new connection.
    205268 *
     
    208271 * @param callid Hash of the incoming call.
    209272 * @param call   Data of the incoming call.
    210  *
    211  */
    212 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     273 * @param arg    Local argument
     274 *
     275 */
     276static void default_client_connection(ipc_callid_t callid, ipc_call_t *call,
     277    void *arg)
    213278{
    214279        ipc_answer_0(callid, ENOENT);
    215280}
    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;
    221281
    222282/** Default fibril function that gets called to handle interrupt notifications.
     
    226286 * @param callid Hash of the incoming call.
    227287 * @param call   Data of the incoming call.
     288 * @param arg    Local argument.
    228289 *
    229290 */
     
    232293}
    233294
    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;
     295static async_client_conn_t client_connection = default_client_connection;
     296static async_interrupt_handler_t interrupt_received = default_interrupt_received;
     297
     298/** Setter for client_connection function pointer.
     299 *
     300 * @param conn Function that will implement a new connection fibril.
     301 *
     302 */
     303void async_set_client_connection(async_client_conn_t conn)
     304{
     305        client_connection = conn;
     306}
     307
     308/** Setter for interrupt_received function pointer.
     309 *
     310 * @param intr Function that will implement a new interrupt
     311 *             notification fibril.
     312 */
     313void async_set_interrupt_received(async_interrupt_handler_t intr)
     314{
     315        interrupt_received = intr;
     316}
     317
     318/** Mutex protecting inactive_exch_list and avail_phone_cv.
     319 *
     320 */
     321static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex);
     322
     323/** List of all currently inactive exchanges.
     324 *
     325 */
     326static LIST_INITIALIZE(inactive_exch_list);
     327
     328/** Condition variable to wait for a phone to become available.
     329 *
     330 */
     331static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
    239332
    240333static hash_table_t client_hash_table;
     
    242335static LIST_INITIALIZE(timeout_list);
    243336
    244 #define CLIENT_HASH_TABLE_BUCKETS  32
    245 #define CONN_HASH_TABLE_BUCKETS    32
    246 
    247337static hash_index_t client_hash(unsigned long key[])
    248338{
    249339        assert(key);
     340       
    250341        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    251342}
     
    253344static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    254345{
     346        assert(key);
     347        assert(keys == 2);
     348        assert(item);
     349       
    255350        client_t *client = hash_table_get_instance(item, client_t, link);
    256         return (key[0] == client->in_task_hash);
     351        return (key[0] == LOWER32(client->in_task_id) &&
     352            (key[1] == UPPER32(client->in_task_id)));
    257353}
    258354
     
    278374{
    279375        assert(key);
     376       
    280377        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    281378}
     
    292389static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    293390{
     391        assert(key);
     392        assert(item);
     393       
    294394        connection_t *conn = hash_table_get_instance(item, connection_t, link);
    295395        return (key[0] == conn->in_phone_hash);
     
    314414void async_insert_timeout(awaiter_t *wd)
    315415{
     416        assert(wd);
     417       
    316418        wd->to_event.occurred = false;
    317419        wd->to_event.inlist = true;
    318420       
    319         link_t *tmp = timeout_list.next;
    320         while (tmp != &timeout_list) {
     421        link_t *tmp = timeout_list.head.next;
     422        while (tmp != &timeout_list.head) {
    321423                awaiter_t *cur
    322424                    = list_get_instance(tmp, awaiter_t, to_event.link);
     
    328430        }
    329431       
    330         list_append(&wd->to_event.link, tmp);
     432        list_insert_before(&wd->to_event.link, tmp);
    331433}
    332434
     
    346448static bool route_call(ipc_callid_t callid, ipc_call_t *call)
    347449{
     450        assert(call);
     451       
    348452        futex_down(&async_futex);
    349453       
     
    400504static int notification_fibril(void *arg)
    401505{
     506        assert(arg);
     507       
    402508        msg_t *msg = (msg_t *) arg;
    403509        interrupt_received(msg->callid, &msg->call);
     
    420526static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
    421527{
     528        assert(call);
     529       
    422530        futex_down(&async_futex);
    423531       
     
    458566ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
    459567{
    460         assert(FIBRIL_connection);
     568        assert(call);
     569        assert(fibril_connection);
    461570       
    462571        /* Why doing this?
    463          * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
     572         * GCC 4.1.0 coughs on fibril_connection-> dereference.
    464573         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    465574         *           I would never expect to find so many errors in
    466575         *           a compiler.
    467576         */
    468         connection_t *conn = FIBRIL_connection;
     577        connection_t *conn = fibril_connection;
    469578       
    470579        futex_down(&async_futex);
     
    518627        }
    519628       
    520         msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link);
     629        msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link);
    521630        list_remove(&msg->link);
    522631       
     
    529638}
    530639
     640static client_t *async_client_get(task_id_t client_id, bool create)
     641{
     642        unsigned long key[2] = {
     643                LOWER32(client_id),
     644                UPPER32(client_id),
     645        };
     646        client_t *client = NULL;
     647
     648        futex_down(&async_futex);
     649        link_t *lnk = hash_table_find(&client_hash_table, key);
     650        if (lnk) {
     651                client = hash_table_get_instance(lnk, client_t, link);
     652                atomic_inc(&client->refcnt);
     653        } else if (create) {
     654                client = malloc(sizeof(client_t));
     655                if (client) {
     656                        client->in_task_id = client_id;
     657                        client->data = async_client_data_create();
     658               
     659                        atomic_set(&client->refcnt, 1);
     660                        hash_table_insert(&client_hash_table, key, &client->link);
     661                }
     662        }
     663
     664        futex_up(&async_futex);
     665        return client;
     666}
     667
     668static void async_client_put(client_t *client)
     669{
     670        bool destroy;
     671        unsigned long key[2] = {
     672                LOWER32(client->in_task_id),
     673                UPPER32(client->in_task_id)
     674        };
     675       
     676        futex_down(&async_futex);
     677       
     678        if (atomic_predec(&client->refcnt) == 0) {
     679                hash_table_remove(&client_hash_table, key, 2);
     680                destroy = true;
     681        } else
     682                destroy = false;
     683       
     684        futex_up(&async_futex);
     685       
     686        if (destroy) {
     687                if (client->data)
     688                        async_client_data_destroy(client->data);
     689               
     690                free(client);
     691        }
     692}
     693
     694void *async_get_client_data(void)
     695{
     696        assert(fibril_connection);
     697        return fibril_connection->client->data;
     698}
     699
     700void *async_get_client_data_by_id(task_id_t client_id)
     701{
     702        client_t *client = async_client_get(client_id, false);
     703        if (!client)
     704                return NULL;
     705        if (!client->data) {
     706                async_client_put(client);
     707                return NULL;
     708        }
     709
     710        return client->data;
     711}
     712
     713void async_put_client_data_by_id(task_id_t client_id)
     714{
     715        client_t *client = async_client_get(client_id, false);
     716
     717        assert(client);
     718        assert(client->data);
     719
     720        /* Drop the reference we got in async_get_client_data_by_hash(). */
     721        async_client_put(client);
     722
     723        /* Drop our own reference we got at the beginning of this function. */
     724        async_client_put(client);
     725}
     726
    531727/** Wrapper for client connection fibril.
    532728 *
     
    541737static int connection_fibril(void *arg)
    542738{
     739        assert(arg);
     740       
    543741        /*
    544742         * Setup fibril-local connection pointer.
    545743         */
    546         FIBRIL_connection = (connection_t *) arg;
    547        
    548         futex_down(&async_futex);
     744        fibril_connection = (connection_t *) arg;
    549745       
    550746        /*
     
    553749         * hash in a new tracking structure.
    554750         */
    555        
    556         unsigned long key = FIBRIL_connection->in_task_hash;
    557         link_t *lnk = hash_table_find(&client_hash_table, &key);
    558        
    559         client_t *client;
    560        
    561         if (lnk) {
    562                 client = hash_table_get_instance(lnk, client_t, link);
    563                 client->refcnt++;
    564         } else {
    565                 client = malloc(sizeof(client_t));
    566                 if (!client) {
    567                         ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
    568                         futex_up(&async_futex);
    569                         return 0;
    570                 }
    571                
    572                 client->in_task_hash = FIBRIL_connection->in_task_hash;
    573                
    574                 async_serialize_start();
    575                 client->data = async_client_data_create();
    576                 async_serialize_end();
    577                
    578                 client->refcnt = 1;
    579                 hash_table_insert(&client_hash_table, &key, &client->link);
    580         }
    581        
    582         futex_up(&async_futex);
    583        
    584         FIBRIL_connection->client = client;
     751
     752        client_t *client = async_client_get(fibril_connection->in_task_id, true);
     753        if (!client) {
     754                ipc_answer_0(fibril_connection->callid, ENOMEM);
     755                return 0;
     756        }
     757
     758        fibril_connection->client = client;
    585759       
    586760        /*
    587761         * Call the connection handler function.
    588762         */
    589         FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    590             &FIBRIL_connection->call);
     763        fibril_connection->cfibril(fibril_connection->callid,
     764            &fibril_connection->call, fibril_connection->carg);
    591765       
    592766        /*
    593767         * Remove the reference for this client task connection.
    594768         */
    595         bool destroy;
    596        
    597         futex_down(&async_futex);
    598        
    599         if (--client->refcnt == 0) {
    600                 hash_table_remove(&client_hash_table, &key, 1);
    601                 destroy = true;
    602         } else
    603                 destroy = false;
    604        
    605         futex_up(&async_futex);
    606        
    607         if (destroy) {
    608                 if (client->data)
    609                         async_client_data_destroy(client->data);
    610                
    611                 free(client);
    612         }
     769        async_client_put(client);
    613770       
    614771        /*
     
    616773         */
    617774        futex_down(&async_futex);
    618         key = FIBRIL_connection->in_phone_hash;
     775        unsigned long key = fibril_connection->in_phone_hash;
    619776        hash_table_remove(&conn_hash_table, &key, 1);
    620777        futex_up(&async_futex);
     
    623780         * Answer all remaining messages with EHANGUP.
    624781         */
    625         while (!list_empty(&FIBRIL_connection->msg_queue)) {
     782        while (!list_empty(&fibril_connection->msg_queue)) {
    626783                msg_t *msg =
    627                     list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
    628                     link);
     784                    list_get_instance(list_first(&fibril_connection->msg_queue),
     785                    msg_t, link);
    629786               
    630787                list_remove(&msg->link);
     
    637794         * i.e. IPC_M_PHONE_HUNGUP.
    638795         */
    639         if (FIBRIL_connection->close_callid)
    640                 ipc_answer_0(FIBRIL_connection->close_callid, EOK);
    641        
    642         free(FIBRIL_connection);
     796        if (fibril_connection->close_callid)
     797                ipc_answer_0(fibril_connection->close_callid, EOK);
     798       
     799        free(fibril_connection);
    643800        return 0;
    644801}
     
    646803/** Create a new fibril for a new connection.
    647804 *
    648  * Create new fibril for connection, fill in connection structures and inserts
     805 * Create new fibril for connection, fill in connection structures and insert
    649806 * it into the hash table, so that later we can easily do routing of messages to
    650807 * particular fibrils.
    651808 *
    652  * @param in_task_hash  Identification of the incoming connection.
     809 * @param in_task_id    Identification of the incoming connection.
    653810 * @param in_phone_hash Identification of the incoming connection.
    654811 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    659816 * @param cfibril       Fibril function that should be called upon opening the
    660817 *                      connection.
     818 * @param carg          Extra argument to pass to the connection fibril
    661819 *
    662820 * @return New fibril id or NULL on failure.
    663821 *
    664822 */
    665 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     823fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
    666824    ipc_callid_t callid, ipc_call_t *call,
    667     void (*cfibril)(ipc_callid_t, ipc_call_t *))
     825    async_client_conn_t cfibril, void *carg)
    668826{
    669827        connection_t *conn = malloc(sizeof(*conn));
     
    675833        }
    676834       
    677         conn->in_task_hash = in_task_hash;
     835        conn->in_task_id = in_task_id;
    678836        conn->in_phone_hash = in_phone_hash;
    679837        list_initialize(&conn->msg_queue);
    680838        conn->callid = callid;
    681839        conn->close_callid = 0;
     840        conn->carg = carg;
    682841       
    683842        if (call)
     
    721880static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    722881{
     882        assert(call);
     883       
    723884        /* Unrouted call - take some default action */
    724885        if ((callid & IPC_CALLID_NOTIFICATION)) {
     
    731892        case IPC_M_CONNECT_ME_TO:
    732893                /* Open new connection with fibril, etc. */
    733                 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
    734                     callid, call, client_connection);
     894                async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
     895                    callid, call, client_connection, NULL);
    735896                return;
    736897        }
     
    752913        futex_down(&async_futex);
    753914       
    754         link_t *cur = timeout_list.next;
    755         while (cur != &timeout_list) {
     915        link_t *cur = list_first(&timeout_list);
     916        while (cur != NULL) {
    756917                awaiter_t *waiter =
    757918                    list_get_instance(cur, awaiter_t, to_event.link);
     
    759920                if (tv_gt(&waiter->to_event.expires, &tv))
    760921                        break;
    761                
    762                 cur = cur->next;
    763922               
    764923                list_remove(&waiter->to_event.link);
     
    774933                        fibril_add_ready(waiter->fid);
    775934                }
     935               
     936                cur = list_first(&timeout_list);
    776937        }
    777938       
     
    800961                suseconds_t timeout;
    801962                if (!list_empty(&timeout_list)) {
    802                         awaiter_t *waiter = list_get_instance(timeout_list.next,
    803                             awaiter_t, to_event.link);
     963                        awaiter_t *waiter = list_get_instance(
     964                            list_first(&timeout_list), awaiter_t, to_event.link);
    804965                       
    805966                        struct timeval tv;
     
    8781039void __async_init(void)
    8791040{
    880         if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
    881             &client_hash_table_ops))
     1041        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
     1042            2, &client_hash_table_ops))
    8821043                abort();
    8831044       
    884         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
    885             &conn_hash_table_ops))
     1045        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
     1046            1, &conn_hash_table_ops))
    8861047                abort();
     1048       
     1049        session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
     1050        if (session_ns == NULL)
     1051                abort();
     1052       
     1053        session_ns->mgmt = EXCHANGE_ATOMIC;
     1054        session_ns->phone = PHONE_NS;
     1055        session_ns->arg1 = 0;
     1056        session_ns->arg2 = 0;
     1057        session_ns->arg3 = 0;
     1058       
     1059        fibril_mutex_initialize(&session_ns->remote_state_mtx);
     1060        session_ns->remote_state_data = NULL;
     1061       
     1062        list_initialize(&session_ns->exch_list);
     1063        fibril_mutex_initialize(&session_ns->mutex);
     1064        atomic_set(&session_ns->refcnt, 0);
    8871065}
    8881066
     
    8991077 *
    9001078 */
    901 static void reply_received(void *arg, int retval, ipc_call_t *data)
    902 {
     1079void reply_received(void *arg, int retval, ipc_call_t *data)
     1080{
     1081        assert(arg);
     1082       
    9031083        futex_down(&async_futex);
    9041084       
     
    9301110 * completion.
    9311111 *
    932  * @param phoneid Handle of the phone that will be used for the send.
    933  * @param method  Service-defined method.
     1112 * @param exch    Exchange for sending the message.
     1113 * @param imethod Service-defined interface and method.
    9341114 * @param arg1    Service-defined payload argument.
    9351115 * @param arg2    Service-defined payload argument.
     
    9421122 *
    9431123 */
    944 aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1124aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9451125    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    9461126{
     1127        if (exch == NULL)
     1128                return 0;
     1129       
    9471130        amsg_t *msg = malloc(sizeof(amsg_t));
    948        
    949         if (!msg)
     1131        if (msg == NULL)
    9501132                return 0;
    9511133       
     
    9611143        msg->wdata.active = true;
    9621144       
    963         ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
     1145        ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
    9641146            reply_received, true);
    9651147       
     
    9721154 * completion.
    9731155 *
    974  * @param phoneid Handle of the phone that will be used for the send.
    975  * @param method  Service-defined method.
     1156 * @param exch    Exchange for sending the message.
     1157 * @param imethod Service-defined interface and method.
    9761158 * @param arg1    Service-defined payload argument.
    9771159 * @param arg2    Service-defined payload argument.
     
    9851167 *
    9861168 */
    987 aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1169aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9881170    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    9891171    ipc_call_t *dataptr)
    9901172{
     1173        if (exch == NULL)
     1174                return 0;
     1175       
    9911176        amsg_t *msg = malloc(sizeof(amsg_t));
    9921177       
    993         if (!msg)
     1178        if (msg == NULL)
    9941179                return 0;
    9951180       
     
    10051190        msg->wdata.active = true;
    10061191       
    1007         ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
    1008             reply_received, true);
     1192        ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
     1193            msg, reply_received, true);
    10091194       
    10101195        return (aid_t) msg;
     
    10201205void async_wait_for(aid_t amsgid, sysarg_t *retval)
    10211206{
     1207        assert(amsgid);
     1208       
    10221209        amsg_t *msg = (amsg_t *) amsgid;
    10231210       
     
    10561243int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)
    10571244{
     1245        assert(amsgid);
     1246       
    10581247        amsg_t *msg = (amsg_t *) amsgid;
    10591248       
     
    11241313}
    11251314
    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 
    11461315/** Pseudo-synchronous message sending - fast version.
    11471316 *
     
    11511320 * transferring more arguments, see the slower async_req_slow().
    11521321 *
    1153  * @param phoneid Hash of the phone through which to make the call.
    1154  * @param method  Method of the call.
     1322 * @param exch    Exchange for sending the message.
     1323 * @param imethod Interface and method of the call.
    11551324 * @param arg1    Service-defined payload argument.
    11561325 * @param arg2    Service-defined payload argument.
     
    11661335 *
    11671336 */
    1168 sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1337sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    11691338    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    11701339    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    11711340{
     1341        if (exch == NULL)
     1342                return ENOENT;
     1343       
    11721344        ipc_call_t result;
    1173         aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
     1345        aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
    11741346            &result);
    11751347       
    11761348        sysarg_t rc;
    1177         async_wait_for(eid, &rc);
     1349        async_wait_for(aid, &rc);
    11781350       
    11791351        if (r1)
     
    11991371 * Send message asynchronously and return only after the reply arrives.
    12001372 *
    1201  * @param phoneid Hash of the phone through which to make the call.
    1202  * @param method  Method of the call.
     1373 * @param exch    Exchange for sending the message.
     1374 * @param imethod Interface and method of the call.
    12031375 * @param arg1    Service-defined payload argument.
    12041376 * @param arg2    Service-defined payload argument.
     
    12151387 *
    12161388 */
    1217 sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1389sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    12181390    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    12191391    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    12201392{
     1393        if (exch == NULL)
     1394                return ENOENT;
     1395       
    12211396        ipc_call_t result;
    1222         aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
     1397        aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5,
    12231398            &result);
    12241399       
    12251400        sysarg_t rc;
    1226         async_wait_for(eid, &rc);
     1401        async_wait_for(aid, &rc);
    12271402       
    12281403        if (r1)
     
    12441419}
    12451420
    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);
     1421void async_msg_0(async_exch_t *exch, sysarg_t imethod)
     1422{
     1423        if (exch != NULL)
     1424                ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
     1425}
     1426
     1427void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
     1428{
     1429        if (exch != NULL)
     1430                ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
     1431}
     1432
     1433void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1434    sysarg_t arg2)
     1435{
     1436        if (exch != NULL)
     1437                ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
     1438                    true);
     1439}
     1440
     1441void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1442    sysarg_t arg2, sysarg_t arg3)
     1443{
     1444        if (exch != NULL)
     1445                ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
     1446                    NULL, true);
     1447}
     1448
     1449void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1450    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1451{
     1452        if (exch != NULL)
     1453                ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1454                    NULL, NULL, true);
     1455}
     1456
     1457void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1458    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1459{
     1460        if (exch != NULL)
     1461                ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1462                    arg5, NULL, NULL, true);
    12791463}
    12801464
     
    13131497}
    13141498
    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);
     1499int async_forward_fast(ipc_callid_t callid, async_exch_t *exch,
     1500    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1501{
     1502        if (exch == NULL)
     1503                return ENOENT;
     1504       
     1505        return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode);
     1506}
     1507
     1508int async_forward_slow(ipc_callid_t callid, async_exch_t *exch,
     1509    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     1510    sysarg_t arg4, sysarg_t arg5, unsigned int mode)
     1511{
     1512        if (exch == NULL)
     1513                return ENOENT;
     1514       
     1515        return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3,
     1516            arg4, arg5, mode);
    13271517}
    13281518
     
    13311521 * Ask through phone for a new connection to some service.
    13321522 *
    1333  * @param phone           Phone handle used for contacting the other side.
     1523 * @param exch            Exchange for sending the message.
    13341524 * @param arg1            User defined argument.
    13351525 * @param arg2            User defined argument.
     
    13371527 * @param client_receiver Connection handing routine.
    13381528 *
    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 {
    1345         sysarg_t task_hash;
     1529 * @return Zero on success or a negative error code.
     1530 *
     1531 */
     1532int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     1533    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
     1534{
     1535        if (exch == NULL)
     1536                return ENOENT;
     1537       
    13461538        sysarg_t phone_hash;
    1347         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1348             NULL, NULL, NULL, &task_hash, &phone_hash);
     1539        sysarg_t rc;
     1540
     1541        aid_t req;
     1542        ipc_call_t answer;
     1543        req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1544            &answer);
     1545        async_wait_for(req, &rc);
     1546        if (rc != EOK)
     1547                return (int) rc;
     1548
     1549        phone_hash = IPC_GET_ARG5(answer);
     1550
     1551        if (client_receiver != NULL)
     1552                async_new_connection(answer.in_task_id, phone_hash, 0, NULL,
     1553                    client_receiver, carg);
     1554       
     1555        return EOK;
     1556}
     1557
     1558/** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
     1559 *
     1560 * Ask through for a cloned connection to some service.
     1561 *
     1562 * @param mgmt Exchange management style.
     1563 * @param exch Exchange for sending the message.
     1564 *
     1565 * @return New session on success or NULL on error.
     1566 *
     1567 */
     1568async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
     1569{
     1570        if (exch == NULL) {
     1571                errno = ENOENT;
     1572                return NULL;
     1573        }
     1574       
     1575        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1576        if (sess == NULL) {
     1577                errno = ENOMEM;
     1578                return NULL;
     1579        }
     1580       
     1581        ipc_call_t result;
     1582       
     1583        amsg_t *msg = malloc(sizeof(amsg_t));
     1584        if (msg == NULL) {
     1585                free(sess);
     1586                errno = ENOMEM;
     1587                return NULL;
     1588        }
     1589       
     1590        msg->done = false;
     1591        msg->dataptr = &result;
     1592       
     1593        msg->wdata.to_event.inlist = false;
     1594       
     1595        /*
     1596         * We may sleep in the next method,
     1597         * but it will use its own means
     1598         */
     1599        msg->wdata.active = true;
     1600       
     1601        ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
     1602            reply_received, true);
     1603       
     1604        sysarg_t rc;
     1605        async_wait_for((aid_t) msg, &rc);
     1606       
     1607        if (rc != EOK) {
     1608                errno = rc;
     1609                free(sess);
     1610                return NULL;
     1611        }
     1612       
     1613        int phone = (int) IPC_GET_ARG5(result);
     1614       
     1615        if (phone < 0) {
     1616                errno = phone;
     1617                free(sess);
     1618                return NULL;
     1619        }
     1620       
     1621        sess->mgmt = mgmt;
     1622        sess->phone = phone;
     1623        sess->arg1 = 0;
     1624        sess->arg2 = 0;
     1625        sess->arg3 = 0;
     1626       
     1627        fibril_mutex_initialize(&sess->remote_state_mtx);
     1628        sess->remote_state_data = NULL;
     1629       
     1630        list_initialize(&sess->exch_list);
     1631        fibril_mutex_initialize(&sess->mutex);
     1632        atomic_set(&sess->refcnt, 0);
     1633       
     1634        return sess;
     1635}
     1636
     1637static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2,
     1638    sysarg_t arg3, sysarg_t arg4)
     1639{
     1640        ipc_call_t result;
     1641       
     1642        amsg_t *msg = malloc(sizeof(amsg_t));
     1643        if (msg == NULL)
     1644                return ENOENT;
     1645       
     1646        msg->done = false;
     1647        msg->dataptr = &result;
     1648       
     1649        msg->wdata.to_event.inlist = false;
     1650       
     1651        /*
     1652         * We may sleep in the next method,
     1653         * but it will use its own means
     1654         */
     1655        msg->wdata.active = true;
     1656       
     1657        ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
     1658            msg, reply_received, true);
     1659       
     1660        sysarg_t rc;
     1661        async_wait_for((aid_t) msg, &rc);
     1662       
    13491663        if (rc != EOK)
    13501664                return rc;
    13511665       
    1352         if (client_receiver != NULL)
    1353                 async_new_connection(task_hash, phone_hash, 0, NULL,
    1354                     client_receiver);
    1355        
    1356         return EOK;
     1666        return (int) IPC_GET_ARG5(result);
    13571667}
    13581668
    13591669/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    13601670 *
    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,
     1671 * Ask through for a new connection to some service.
     1672 *
     1673 * @param mgmt Exchange management style.
     1674 * @param exch Exchange for sending the message.
     1675 * @param arg1 User defined argument.
     1676 * @param arg2 User defined argument.
     1677 * @param arg3 User defined argument.
     1678 *
     1679 * @return New session on success or NULL on error.
     1680 *
     1681 */
     1682async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch,
     1683    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1684{
     1685        if (exch == NULL) {
     1686                errno = ENOENT;
     1687                return NULL;
     1688        }
     1689       
     1690        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1691        if (sess == NULL) {
     1692                errno = ENOMEM;
     1693                return NULL;
     1694        }
     1695       
     1696        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1697            0);
     1698       
     1699        if (phone < 0) {
     1700                errno = phone;
     1701                free(sess);
     1702                return NULL;
     1703        }
     1704       
     1705        sess->mgmt = mgmt;
     1706        sess->phone = phone;
     1707        sess->arg1 = arg1;
     1708        sess->arg2 = arg2;
     1709        sess->arg3 = arg3;
     1710       
     1711        fibril_mutex_initialize(&sess->remote_state_mtx);
     1712        sess->remote_state_data = NULL;
     1713       
     1714        list_initialize(&sess->exch_list);
     1715        fibril_mutex_initialize(&sess->mutex);
     1716        atomic_set(&sess->refcnt, 0);
     1717       
     1718        return sess;
     1719}
     1720
     1721/** Set arguments for new connections.
     1722 *
     1723 * FIXME This is an ugly hack to work around the problem that parallel
     1724 * exchanges are implemented using parallel connections. When we create
     1725 * a callback session, the framework does not know arguments for the new
     1726 * connections.
     1727 *
     1728 * The proper solution seems to be to implement parallel exchanges using
     1729 * tagging.
     1730 */
     1731void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2,
    13721732    sysarg_t arg3)
    13731733{
    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);
    1377        
    1378         if (rc != EOK)
    1379                 return rc;
    1380        
    1381         return newphid;
     1734        sess->arg1 = arg1;
     1735        sess->arg2 = arg2;
     1736        sess->arg3 = arg3;
    13821737}
    13831738
     
    13871742 * success.
    13881743 *
    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;
     1744 * @param mgmt Exchange management style.
     1745 * @param exch Exchange for sending the message.
     1746 * @param arg1 User defined argument.
     1747 * @param arg2 User defined argument.
     1748 * @param arg3 User defined argument.
     1749 *
     1750 * @return New session on success or NULL on error.
     1751 *
     1752 */
     1753async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch,
     1754    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1755{
     1756        if (exch == NULL) {
     1757                errno = ENOENT;
     1758                return NULL;
     1759        }
     1760       
     1761        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1762        if (sess == NULL) {
     1763                errno = ENOMEM;
     1764                return NULL;
     1765        }
     1766       
     1767        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1768            IPC_FLAG_BLOCKING);
     1769       
     1770        if (phone < 0) {
     1771                errno = phone;
     1772                free(sess);
     1773                return NULL;
     1774        }
     1775       
     1776        sess->mgmt = mgmt;
     1777        sess->phone = phone;
     1778        sess->arg1 = arg1;
     1779        sess->arg2 = arg2;
     1780        sess->arg3 = arg3;
     1781       
     1782        fibril_mutex_initialize(&sess->remote_state_mtx);
     1783        sess->remote_state_data = NULL;
     1784       
     1785        list_initialize(&sess->exch_list);
     1786        fibril_mutex_initialize(&sess->mutex);
     1787        atomic_set(&sess->refcnt, 0);
     1788       
     1789        return sess;
    14081790}
    14091791
     
    14111793 *
    14121794 */
    1413 int async_connect_kbox(task_id_t id)
    1414 {
    1415         return ipc_connect_kbox(id);
     1795async_sess_t *async_connect_kbox(task_id_t id)
     1796{
     1797        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1798        if (sess == NULL) {
     1799                errno = ENOMEM;
     1800                return NULL;
     1801        }
     1802       
     1803        int phone = ipc_connect_kbox(id);
     1804        if (phone < 0) {
     1805                errno = phone;
     1806                free(sess);
     1807                return NULL;
     1808        }
     1809       
     1810        sess->mgmt = EXCHANGE_ATOMIC;
     1811        sess->phone = phone;
     1812        sess->arg1 = 0;
     1813        sess->arg2 = 0;
     1814        sess->arg3 = 0;
     1815       
     1816        fibril_mutex_initialize(&sess->remote_state_mtx);
     1817        sess->remote_state_data = NULL;
     1818       
     1819        list_initialize(&sess->exch_list);
     1820        fibril_mutex_initialize(&sess->mutex);
     1821        atomic_set(&sess->refcnt, 0);
     1822       
     1823        return sess;
     1824}
     1825
     1826static int async_hangup_internal(int phone)
     1827{
     1828        return ipc_hangup(phone);
    14161829}
    14171830
    14181831/** Wrapper for ipc_hangup.
    14191832 *
    1420  * @param phone Phone handle to hung up.
     1833 * @param sess Session to hung up.
    14211834 *
    14221835 * @return Zero on success or a negative error code.
    14231836 *
    14241837 */
    1425 int async_hangup(int phone)
    1426 {
    1427         return ipc_hangup(phone);
     1838int async_hangup(async_sess_t *sess)
     1839{
     1840        async_exch_t *exch;
     1841       
     1842        assert(sess);
     1843       
     1844        if (atomic_get(&sess->refcnt) > 0)
     1845                return EBUSY;
     1846       
     1847        fibril_mutex_lock(&async_sess_mutex);
     1848
     1849        int rc = async_hangup_internal(sess->phone);
     1850       
     1851        while (!list_empty(&sess->exch_list)) {
     1852                exch = (async_exch_t *)
     1853                    list_get_instance(list_first(&sess->exch_list),
     1854                    async_exch_t, sess_link);
     1855               
     1856                list_remove(&exch->sess_link);
     1857                list_remove(&exch->global_link);
     1858                async_hangup_internal(exch->phone);
     1859                free(exch);
     1860        }
     1861
     1862        free(sess);
     1863       
     1864        fibril_mutex_unlock(&async_sess_mutex);
     1865       
     1866        return rc;
    14281867}
    14291868
     
    14341873}
    14351874
     1875/** Start new exchange in a session.
     1876 *
     1877 * @param session Session.
     1878 *
     1879 * @return New exchange or NULL on error.
     1880 *
     1881 */
     1882async_exch_t *async_exchange_begin(async_sess_t *sess)
     1883{
     1884        if (sess == NULL)
     1885                return NULL;
     1886       
     1887        async_exch_t *exch;
     1888       
     1889        fibril_mutex_lock(&async_sess_mutex);
     1890       
     1891        if (!list_empty(&sess->exch_list)) {
     1892                /*
     1893                 * There are inactive exchanges in the session.
     1894                 */
     1895                exch = (async_exch_t *)
     1896                    list_get_instance(list_first(&sess->exch_list),
     1897                    async_exch_t, sess_link);
     1898               
     1899                list_remove(&exch->sess_link);
     1900                list_remove(&exch->global_link);
     1901        } else {
     1902                /*
     1903                 * There are no available exchanges in the session.
     1904                 */
     1905               
     1906                if ((sess->mgmt == EXCHANGE_ATOMIC) ||
     1907                    (sess->mgmt == EXCHANGE_SERIALIZE)) {
     1908                        exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1909                        if (exch != NULL) {
     1910                                link_initialize(&exch->sess_link);
     1911                                link_initialize(&exch->global_link);
     1912                                exch->sess = sess;
     1913                                exch->phone = sess->phone;
     1914                        }
     1915                } else {  /* EXCHANGE_PARALLEL */
     1916                        /*
     1917                         * Make a one-time attempt to connect a new data phone.
     1918                         */
     1919                       
     1920                        int phone;
     1921                       
     1922retry:
     1923                        phone = async_connect_me_to_internal(sess->phone, sess->arg1,
     1924                            sess->arg2, sess->arg3, 0);
     1925                        if (phone >= 0) {
     1926                                exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1927                                if (exch != NULL) {
     1928                                        link_initialize(&exch->sess_link);
     1929                                        link_initialize(&exch->global_link);
     1930                                        exch->sess = sess;
     1931                                        exch->phone = phone;
     1932                                } else
     1933                                        async_hangup_internal(phone);
     1934                        } else if (!list_empty(&inactive_exch_list)) {
     1935                                /*
     1936                                 * We did not manage to connect a new phone. But we
     1937                                 * can try to close some of the currently inactive
     1938                                 * connections in other sessions and try again.
     1939                                 */
     1940                                exch = (async_exch_t *)
     1941                                    list_get_instance(list_first(&inactive_exch_list),
     1942                                    async_exch_t, global_link);
     1943                               
     1944                                list_remove(&exch->sess_link);
     1945                                list_remove(&exch->global_link);
     1946                                async_hangup_internal(exch->phone);
     1947                                free(exch);
     1948                                goto retry;
     1949                        } else {
     1950                                /*
     1951                                 * Wait for a phone to become available.
     1952                                 */
     1953                                fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
     1954                                goto retry;
     1955                        }
     1956                }
     1957        }
     1958       
     1959        fibril_mutex_unlock(&async_sess_mutex);
     1960       
     1961        if (exch != NULL) {
     1962                atomic_inc(&sess->refcnt);
     1963               
     1964                if (sess->mgmt == EXCHANGE_SERIALIZE)
     1965                        fibril_mutex_lock(&sess->mutex);
     1966        }
     1967       
     1968        return exch;
     1969}
     1970
     1971/** Finish an exchange.
     1972 *
     1973 * @param exch Exchange to finish.
     1974 *
     1975 */
     1976void async_exchange_end(async_exch_t *exch)
     1977{
     1978        if (exch == NULL)
     1979                return;
     1980       
     1981        async_sess_t *sess = exch->sess;
     1982       
     1983        atomic_dec(&sess->refcnt);
     1984       
     1985        if (sess->mgmt == EXCHANGE_SERIALIZE)
     1986                fibril_mutex_unlock(&sess->mutex);
     1987       
     1988        fibril_mutex_lock(&async_sess_mutex);
     1989       
     1990        list_append(&exch->sess_link, &sess->exch_list);
     1991        list_append(&exch->global_link, &inactive_exch_list);
     1992        fibril_condvar_signal(&avail_phone_cv);
     1993       
     1994        fibril_mutex_unlock(&async_sess_mutex);
     1995}
     1996
    14361997/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
    14371998 *
    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.
     1999 * @param exch  Exchange for sending the message.
     2000 * @param dst   Destination address space area base.
     2001 * @param size  Size of the destination address space area.
     2002 * @param arg   User defined argument.
     2003 * @param flags Storage for the received flags. Can be NULL.
    14432004 *
    14442005 * @return Zero on success or a negative error code from errno.h.
    14452006 *
    14462007 */
    1447 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1448     unsigned int *flags)
    1449 {
     2008int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
     2009    sysarg_t arg, unsigned int *flags)
     2010{
     2011        if (exch == NULL)
     2012                return ENOENT;
     2013       
    14502014        sysarg_t tmp_flags;
    1451         int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     2015        int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
    14522016            (sysarg_t) size, arg, NULL, &tmp_flags);
    14532017       
     
    15072071/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
    15082072 *
    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.
     2073 * @param exch  Exchange for sending the message.
     2074 * @param src   Source address space area base address.
     2075 * @param flags Flags to be used for sharing. Bits can be only cleared.
    15122076 *
    15132077 * @return Zero on success or a negative error code from errno.h.
    15142078 *
    15152079 */
    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,
     2080int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags)
     2081{
     2082        if (exch == NULL)
     2083                return ENOENT;
     2084       
     2085        return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
    15192086            (sysarg_t) flags);
    15202087}
     
    15692136}
    15702137
     2138/** Start IPC_M_DATA_READ using the async framework.
     2139 *
     2140 * @param exch    Exchange for sending the message.
     2141 * @param dst     Address of the beginning of the destination buffer.
     2142 * @param size    Size of the destination buffer (in bytes).
     2143 * @param dataptr Storage of call data (arg 2 holds actual data size).
     2144 *
     2145 * @return Hash of the sent message or 0 on error.
     2146 *
     2147 */
     2148aid_t async_data_read(async_exch_t *exch, void *dst, size_t size,
     2149    ipc_call_t *dataptr)
     2150{
     2151        return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst,
     2152            (sysarg_t) size, dataptr);
     2153}
     2154
    15712155/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15722156 *
    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.
     2157 * @param exch Exchange for sending the message.
     2158 * @param dst  Address of the beginning of the destination buffer.
     2159 * @param size Size of the destination buffer.
    15772160 *
    15782161 * @return Zero on success or a negative error code from errno.h.
    15792162 *
    15802163 */
    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);
     2164int async_data_read_start(async_exch_t *exch, void *dst, size_t size)
     2165{
     2166        if (exch == NULL)
     2167                return ENOENT;
     2168       
     2169        return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst,
     2170            (sysarg_t) size);
    15862171}
    15872172
     
    16382223 *
    16392224 */
    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 {
     2225int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2226    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2227    ipc_call_t *dataptr)
     2228{
     2229        if (exch == NULL)
     2230                return ENOENT;
     2231       
    16432232        ipc_callid_t callid;
    16442233        if (!async_data_read_receive(&callid, NULL)) {
     
    16472236        }
    16482237       
    1649         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2238        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    16502239            dataptr);
    16512240        if (msg == 0) {
     
    16542243        }
    16552244       
    1656         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2245        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    16572246            IPC_FF_ROUTE_FROM_ME);
    16582247        if (retval != EOK) {
     
    16702259/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    16712260 *
    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.
     2261 * @param exch Exchange for sending the message.
     2262 * @param src  Address of the beginning of the source buffer.
     2263 * @param size Size of the source buffer.
    16762264 *
    16772265 * @return Zero on success or a negative error code from errno.h.
    16782266 *
    16792267 */
    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);
     2268int async_data_write_start(async_exch_t *exch, const void *src, size_t size)
     2269{
     2270        if (exch == NULL)
     2271                return ENOENT;
     2272       
     2273        return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src,
     2274            (sysarg_t) size);
    16862275}
    16872276
     
    17592348    size_t *received)
    17602349{
     2350        assert(data);
     2351       
    17612352        ipc_callid_t callid;
    17622353        size_t size;
     
    18262417 *
    18272418 */
    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 {
     2419int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2420    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2421    ipc_call_t *dataptr)
     2422{
     2423        if (exch == NULL)
     2424                return ENOENT;
     2425       
    18312426        ipc_callid_t callid;
    18322427        if (!async_data_write_receive(&callid, NULL)) {
     
    18352430        }
    18362431       
    1837         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2432        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    18382433            dataptr);
    18392434        if (msg == 0) {
     
    18422437        }
    18432438       
    1844         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2439        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    18452440            IPC_FF_ROUTE_FROM_ME);
    18462441        if (retval != EOK) {
     
    18562451}
    18572452
     2453/** Wrapper for sending an exchange over different exchange for cloning
     2454 *
     2455 * @param exch       Exchange to be used for sending.
     2456 * @param clone_exch Exchange to be cloned.
     2457 *
     2458 */
     2459int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
     2460{
     2461        return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
     2462}
     2463
     2464/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
     2465 *
     2466 * If the current call is IPC_M_CONNECTION_CLONE then a new
     2467 * async session is created for the accepted phone.
     2468 *
     2469 * @param mgmt Exchange management style.
     2470 *
     2471 * @return New async session or NULL on failure.
     2472 *
     2473 */
     2474async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
     2475{
     2476        /* Accept the phone */
     2477        ipc_call_t call;
     2478        ipc_callid_t callid = async_get_call(&call);
     2479        int phone = (int) IPC_GET_ARG1(call);
     2480       
     2481        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
     2482            (phone < 0)) {
     2483                async_answer_0(callid, EINVAL);
     2484                return NULL;
     2485        }
     2486       
     2487        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2488        if (sess == NULL) {
     2489                async_answer_0(callid, ENOMEM);
     2490                return NULL;
     2491        }
     2492       
     2493        sess->mgmt = mgmt;
     2494        sess->phone = phone;
     2495        sess->arg1 = 0;
     2496        sess->arg2 = 0;
     2497        sess->arg3 = 0;
     2498       
     2499        fibril_mutex_initialize(&sess->remote_state_mtx);
     2500        sess->remote_state_data = NULL;
     2501       
     2502        list_initialize(&sess->exch_list);
     2503        fibril_mutex_initialize(&sess->mutex);
     2504        atomic_set(&sess->refcnt, 0);
     2505       
     2506        /* Acknowledge the cloned phone */
     2507        async_answer_0(callid, EOK);
     2508       
     2509        return sess;
     2510}
     2511
     2512/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
     2513 *
     2514 * If the current call is IPC_M_CONNECT_TO_ME then a new
     2515 * async session is created for the accepted phone.
     2516 *
     2517 * @param mgmt Exchange management style.
     2518 *
     2519 * @return New async session.
     2520 * @return NULL on failure.
     2521 *
     2522 */
     2523async_sess_t *async_callback_receive(exch_mgmt_t mgmt)
     2524{
     2525        /* Accept the phone */
     2526        ipc_call_t call;
     2527        ipc_callid_t callid = async_get_call(&call);
     2528        int phone = (int) IPC_GET_ARG5(call);
     2529       
     2530        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
     2531            (phone < 0)) {
     2532                async_answer_0(callid, EINVAL);
     2533                return NULL;
     2534        }
     2535       
     2536        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2537        if (sess == NULL) {
     2538                async_answer_0(callid, ENOMEM);
     2539                return NULL;
     2540        }
     2541       
     2542        sess->mgmt = mgmt;
     2543        sess->phone = phone;
     2544        sess->arg1 = 0;
     2545        sess->arg2 = 0;
     2546        sess->arg3 = 0;
     2547       
     2548        fibril_mutex_initialize(&sess->remote_state_mtx);
     2549        sess->remote_state_data = NULL;
     2550       
     2551        list_initialize(&sess->exch_list);
     2552        fibril_mutex_initialize(&sess->mutex);
     2553        atomic_set(&sess->refcnt, 0);
     2554       
     2555        /* Acknowledge the connected phone */
     2556        async_answer_0(callid, EOK);
     2557       
     2558        return sess;
     2559}
     2560
     2561/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
     2562 *
     2563 * If the call is IPC_M_CONNECT_TO_ME then a new
     2564 * async session is created. However, the phone is
     2565 * not accepted automatically.
     2566 *
     2567 * @param mgmt   Exchange management style.
     2568 * @param call   Call data.
     2569 *
     2570 * @return New async session.
     2571 * @return NULL on failure.
     2572 * @return NULL if the call is not IPC_M_CONNECT_TO_ME.
     2573 *
     2574 */
     2575async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call)
     2576{
     2577        int phone = (int) IPC_GET_ARG5(*call);
     2578       
     2579        if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) ||
     2580            (phone < 0))
     2581                return NULL;
     2582       
     2583        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2584        if (sess == NULL)
     2585                return NULL;
     2586       
     2587        sess->mgmt = mgmt;
     2588        sess->phone = phone;
     2589        sess->arg1 = 0;
     2590        sess->arg2 = 0;
     2591        sess->arg3 = 0;
     2592       
     2593        fibril_mutex_initialize(&sess->remote_state_mtx);
     2594        sess->remote_state_data = NULL;
     2595       
     2596        list_initialize(&sess->exch_list);
     2597        fibril_mutex_initialize(&sess->mutex);
     2598        atomic_set(&sess->refcnt, 0);
     2599       
     2600        return sess;
     2601}
     2602
     2603int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     2604    sysarg_t arg3, async_exch_t *other_exch)
     2605{
     2606        return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
     2607            arg1, arg2, arg3, 0, other_exch->phone);
     2608}
     2609
     2610bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1,
     2611    sysarg_t *arg2, sysarg_t *arg3)
     2612{
     2613        assert(callid);
     2614
     2615        ipc_call_t call;
     2616        *callid = async_get_call(&call);
     2617
     2618        if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
     2619                return false;
     2620       
     2621        if (arg1)
     2622                *arg1 = IPC_GET_ARG1(call);
     2623        if (arg2)
     2624                *arg2 = IPC_GET_ARG2(call);
     2625        if (arg3)
     2626                *arg3 = IPC_GET_ARG3(call);
     2627
     2628        return true;
     2629}
     2630
     2631int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch)
     2632{
     2633        return ipc_answer_1(callid, EOK, other_exch->phone);
     2634}
     2635
     2636/** Lock and get session remote state
     2637 *
     2638 * Lock and get the local replica of the remote state
     2639 * in stateful sessions. The call should be paired
     2640 * with async_remote_state_release*().
     2641 *
     2642 * @param[in] sess Stateful session.
     2643 *
     2644 * @return Local replica of the remote state.
     2645 *
     2646 */
     2647void *async_remote_state_acquire(async_sess_t *sess)
     2648{
     2649        fibril_mutex_lock(&sess->remote_state_mtx);
     2650        return sess->remote_state_data;
     2651}
     2652
     2653/** Update the session remote state
     2654 *
     2655 * Update the local replica of the remote state
     2656 * in stateful sessions. The remote state must
     2657 * be already locked.
     2658 *
     2659 * @param[in] sess  Stateful session.
     2660 * @param[in] state New local replica of the remote state.
     2661 *
     2662 */
     2663void async_remote_state_update(async_sess_t *sess, void *state)
     2664{
     2665        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2666        sess->remote_state_data = state;
     2667}
     2668
     2669/** Release the session remote state
     2670 *
     2671 * Unlock the local replica of the remote state
     2672 * in stateful sessions.
     2673 *
     2674 * @param[in] sess Stateful session.
     2675 *
     2676 */
     2677void async_remote_state_release(async_sess_t *sess)
     2678{
     2679        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2680       
     2681        fibril_mutex_unlock(&sess->remote_state_mtx);
     2682}
     2683
     2684/** Release the session remote state and end an exchange
     2685 *
     2686 * Unlock the local replica of the remote state
     2687 * in stateful sessions. This is convenience function
     2688 * which gets the session pointer from the exchange
     2689 * and also ends the exchange.
     2690 *
     2691 * @param[in] exch Stateful session's exchange.
     2692 *
     2693 */
     2694void async_remote_state_release_exchange(async_exch_t *exch)
     2695{
     2696        if (exch == NULL)
     2697                return;
     2698       
     2699        async_sess_t *sess = exch->sess;
     2700        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2701       
     2702        async_exchange_end(exch);
     2703        fibril_mutex_unlock(&sess->remote_state_mtx);
     2704}
     2705
    18582706/** @}
    18592707 */
  • uspace/lib/c/generic/clipboard.c

    r2bdf8313 rb0f00a9  
    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/ddi.c

    r2bdf8313 rb0f00a9  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
     35#include <sys/types.h>
     36#include <abi/ddi/arg.h>
    3537#include <ddi.h>
    3638#include <libarch/ddi.h>
     
    4042#include <align.h>
    4143#include <libarch/config.h>
    42 #include <kernel/ddi/ddi_arg.h>
    4344
    4445/** Return unique device number.
  • uspace/lib/c/generic/device/char_dev.c

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    11/*
    22 * Copyright (c) 2007 Josef Cejka
    3  * Copyright (c) 2009 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * Copyright (c) 2010 Lenka Trochtova
    55 * All rights reserved.
     
    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_PARALLEL,
     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_PARALLEL, 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();
     181        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    104182       
    105183        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));
     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       
    109189        if (retval != EOK) {
    110190                async_wait_for(req, NULL);
    111                 async_serialize_end();
    112                 return -1;
     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, conn, 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);
     222        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     223       
    183224        ipc_call_t answer;
    184 
    185         aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     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));
     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);
     260       
     261        async_wait_for(req, &retval);
     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       
     270        return retval;
     271}
     272
     273int devman_add_device_to_category(devman_handle_t devman_handle,
     274    const char *cat_name)
     275{
     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_CATEGORY,
     280            devman_handle, &answer);
     281        sysarg_t retval = async_data_write_start(exch, cat_name,
     282            str_size(cat_name));
     283       
     284        devman_exchange_end(exch);
     285       
    189286        if (retval != EOK) {
    190287                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);
     288                return retval;
     289        }
    196290       
    197291        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);
     292        return retval;
     293}
     294
     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);
    208303        else
    209                 fun_handle = -1;
    210        
    211         *funh = fun_handle;
    212 
    213         return retval;
    214 }
    215 
    216 int devman_add_device_to_class(devman_handle_t devman_handle,
    217     const char *class_name)
    218 {
    219         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    220        
    221         if (phone < 0)
    222                 return phone;
    223        
    224         async_serialize_start();
     304                sess = service_connect(mgmt, SERVICE_DEVMAN,
     305                            DEVMAN_CONNECT_TO_DEVICE, handle);
     306       
     307        return sess;
     308}
     309
     310/** Remove function from device.
     311 *
     312 * Request devman to remove function owned by this driver task.
     313 * @param funh      Devman handle of the function
     314 *
     315 * @return EOK on success or negative error code.
     316 */
     317int devman_remove_function(devman_handle_t funh)
     318{
     319        async_exch_t *exch;
     320        sysarg_t retval;
     321       
     322        exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     323        retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh);
     324        devman_exchange_end(exch);
     325       
     326        return (int) retval;
     327}
     328
     329int devman_drv_fun_online(devman_handle_t funh)
     330{
     331        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     332        if (exch == NULL)
     333                return ENOMEM;
     334       
     335        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
     336       
     337        devman_exchange_end(exch);
     338        return (int) retval;
     339}
     340
     341int devman_drv_fun_offline(devman_handle_t funh)
     342{
     343        async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
     344        if (exch == NULL)
     345                return ENOMEM;
     346       
     347        sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
     348       
     349        devman_exchange_end(exch);
     350        return (int) retval;
     351}
     352
     353async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
     354    devman_handle_t handle, unsigned int flags)
     355{
     356        async_sess_t *sess;
     357       
     358        if (flags & IPC_FLAG_BLOCKING)
     359                sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
     360                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     361        else
     362                sess = service_connect(mgmt, SERVICE_DEVMAN,
     363                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     364       
     365        return sess;
     366}
     367
     368int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     369    unsigned int flags)
     370{
     371        async_exch_t *exch;
     372       
     373        if (flags & IPC_FLAG_BLOCKING)
     374                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     375        else {
     376                exch = devman_exchange_begin(DEVMAN_CLIENT);
     377                if (exch == NULL)
     378                        return ENOMEM;
     379        }
     380       
    225381        ipc_call_t answer;
    226         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
    227             devman_handle, &answer);
    228        
    229         sysarg_t retval = async_data_write_start(phone, class_name,
    230             str_size(class_name));
     382        aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
     383            &answer);
     384        sysarg_t retval = async_data_write_start(exch, pathname,
     385            str_size(pathname));
     386       
     387        devman_exchange_end(exch);
     388       
    231389        if (retval != EOK) {
    232390                async_wait_for(req, NULL);
    233                 async_serialize_end();
    234391                return retval;
    235392        }
    236393       
    237394        async_wait_for(req, &retval);
    238         async_serialize_end();
    239        
    240         return retval;
    241 }
    242 
    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;
    291 }
    292 
    293 int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
    294     unsigned int flags)
    295 {
    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,
    305             &answer);
    306        
    307         sysarg_t retval = async_data_write_start(phone, pathname,
    308             str_size(pathname));
    309         if (retval != EOK) {
    310                 async_wait_for(req, NULL);
    311                 async_serialize_end();
    312                 return retval;
    313         }
    314        
    315         async_wait_for(req, &retval);
    316        
    317         async_serialize_end();
    318395       
    319396        if (retval != EOK) {
    320397                if (handle != NULL)
    321398                        *handle = (devman_handle_t) -1;
     399               
    322400                return retval;
    323401        }
     
    329407}
    330408
    331 int devman_device_get_handle_by_class(const char *classname,
    332     const char *devname, devman_handle_t *handle, unsigned int flags)
    333 {
    334         int phone = devman_get_phone(DEVMAN_CLIENT, flags);
    335 
    336         if (phone < 0)
    337                 return phone;
    338 
    339         async_serialize_start();
    340 
     409static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
     410    size_t buf_size)
     411{
     412        async_exch_t *exch;
     413        ipc_call_t dreply;
     414        size_t act_size;
     415        sysarg_t dretval;
     416       
     417        exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
     418       
    341419        ipc_call_t answer;
    342         aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
    343             flags, &answer);
    344 
    345         sysarg_t retval = async_data_write_start(phone, classname,
    346             str_size(classname));
     420        aid_t req = async_send_1(exch, method, arg1, &answer);
     421        aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
     422        async_wait_for(dreq, &dretval);
     423       
     424        devman_exchange_end(exch);
     425       
     426        if (dretval != EOK) {
     427                async_wait_for(req, NULL);
     428                return dretval;
     429        }
     430       
     431        sysarg_t retval;
     432        async_wait_for(req, &retval);
     433       
     434        if (retval != EOK)
     435                return retval;
     436       
     437        act_size = IPC_GET_ARG2(dreply);
     438        assert(act_size <= buf_size - 1);
     439        buf[act_size] = '\0';
     440       
     441        return EOK;
     442}
     443
     444int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
     445{
     446        return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf,
     447            buf_size);
     448}
     449
     450int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
     451{
     452        return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf,
     453            buf_size);
     454}
     455
     456int devman_fun_online(devman_handle_t funh)
     457{
     458        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     459        if (exch == NULL)
     460                return ENOMEM;
     461       
     462        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
     463       
     464        devman_exchange_end(exch);
     465        return (int) retval;
     466}
     467
     468int devman_fun_offline(devman_handle_t funh)
     469{
     470        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     471        if (exch == NULL)
     472                return ENOMEM;
     473       
     474        sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
     475       
     476        devman_exchange_end(exch);
     477        return (int) retval;
     478}
     479
     480static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
     481    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
     482{
     483        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     484
     485        ipc_call_t answer;
     486        aid_t req = async_send_1(exch, method, arg1, &answer);
     487        int rc = async_data_read_start(exch, handle_buf, buf_size);
     488       
     489        devman_exchange_end(exch);
     490       
     491        if (rc != EOK) {
     492                async_wait_for(req, NULL);
     493                return rc;
     494        }
     495       
     496        sysarg_t retval;
     497        async_wait_for(req, &retval);
     498       
    347499        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,
    353             str_size(devname));
    354         if (retval != EOK) {
    355                 async_wait_for(req, NULL);
    356                 async_serialize_end();
    357                 return retval;
    358         }
    359 
    360         async_wait_for(req, &retval);
    361 
    362         async_serialize_end();
    363 
    364         if (retval != EOK) {
    365                 if (handle != NULL)
    366                         *handle = (devman_handle_t) -1;
    367                 return retval;
    368         }
    369 
    370         if (handle != NULL)
    371                 *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    372 
    373         return retval;
    374 }
    375 
     500                return retval;
     501        }
     502       
     503        *act_size = IPC_GET_ARG1(answer);
     504        return EOK;
     505}
     506
     507/** Get list of handles.
     508 *
     509 * Returns an allocated array of handles.
     510 *
     511 * @param method        IPC method
     512 * @param arg1          IPC argument 1
     513 * @param data          Place to store pointer to array of handles
     514 * @param count         Place to store number of handles
     515 * @return              EOK on success or negative error code
     516 */
     517static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
     518    devman_handle_t **data, size_t *count)
     519{
     520        devman_handle_t *handles;
     521        size_t act_size;
     522        size_t alloc_size;
     523        int rc;
     524
     525        *data = NULL;
     526        act_size = 0;   /* silence warning */
     527
     528        rc = devman_get_handles_once(method, arg1, NULL, 0,
     529            &act_size);
     530        if (rc != EOK)
     531                return rc;
     532
     533        alloc_size = act_size;
     534        handles = malloc(alloc_size);
     535        if (handles == NULL)
     536                return ENOMEM;
     537
     538        while (true) {
     539                rc = devman_get_handles_once(method, arg1, handles, alloc_size,
     540                    &act_size);
     541                if (rc != EOK)
     542                        return rc;
     543
     544                if (act_size <= alloc_size)
     545                        break;
     546
     547                alloc_size *= 2;
     548                free(handles);
     549
     550                handles = malloc(alloc_size);
     551                if (handles == NULL)
     552                        return ENOMEM;
     553        }
     554
     555        *count = act_size / sizeof(devman_handle_t);
     556        *data = handles;
     557        return EOK;
     558}
     559
     560int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
     561{
     562        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     563        if (exch == NULL)
     564                return ENOMEM;
     565       
     566        sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
     567            funh, devh);
     568       
     569        devman_exchange_end(exch);
     570        return (int) retval;
     571}
     572
     573int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
     574    size_t *count)
     575{
     576        return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
     577            devh, funcs, count);
     578}
     579
     580int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle)
     581{
     582        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     583        if (exch == NULL)
     584                return ENOMEM;
     585       
     586        sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE,
     587            sid, handle);
     588       
     589        devman_exchange_end(exch);
     590        return (int) retval;
     591}
    376592
    377593/** @}
  • uspace/lib/c/generic/elf/elf_load.c

    r2bdf8313 rb0f00a9  
    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>
     
    5556#include <entry_point.h>
    5657
    57 #include "elf.h"
    58 #include "elf_load.h"
     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 *
     
    160147        int i, rc;
    161148
    162         rc = my_read(elf->fd, header, sizeof(elf_header_t));
    163         if (rc < 0) {
     149        rc = read_all(elf->fd, header, sizeof(elf_header_t));
     150        if (rc != sizeof(elf_header_t)) {
    164151                DPRINTF("Read error.\n");
    165152                return EE_INVALID;
     
    222209                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    223210
    224                 rc = my_read(elf->fd, &segment_hdr,
     211                rc = read_all(elf->fd, &segment_hdr,
    225212                    sizeof(elf_segment_header_t));
    226                 if (rc < 0) {
     213                if (rc != sizeof(elf_segment_header_t)) {
    227214                        DPRINTF("Read error.\n");
    228215                        return EE_INVALID;
     
    244231                    + i * sizeof(elf_section_header_t), SEEK_SET);
    245232
    246                 rc = my_read(elf->fd, &section_hdr,
     233                rc = read_all(elf->fd, &section_hdr,
    247234                    sizeof(elf_section_header_t));
    248                 if (rc < 0) {
     235                if (rc != sizeof(elf_section_header_t)) {
    249236                        DPRINTF("Read error.\n");
    250237                        return EE_INVALID;
     
    334321        uintptr_t seg_addr;
    335322        size_t mem_sz;
    336         int rc;
     323        ssize_t rc;
    337324
    338325        bias = elf->bias;
     
    412399                if (now > left) now = left;
    413400
    414                 rc = my_read(elf->fd, dp, now);
    415 
    416                 if (rc < 0) {
     401                rc = read_all(elf->fd, dp, now);
     402
     403                if (rc != (ssize_t) now) {
    417404                        DPRINTF("Read error.\n");
    418405                        return EE_INVALID;
  • uspace/lib/c/generic/event.c

    r2bdf8313 rb0f00a9  
    3939#include <libc.h>
    4040#include <event.h>
    41 #include <kernel/ipc/event_types.h>
    4241
    4342/** Subscribe event notifications.
     
    5049 */
    5150int event_subscribe(event_type_t evno, sysarg_t imethod)
     51{
     52        return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
     53            (sysarg_t) imethod);
     54}
     55
     56int event_task_subscribe(event_task_type_t evno, sysarg_t imethod)
    5257{
    5358        return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
     
    6772}
    6873
     74int event_task_unmask(event_task_type_t evno)
     75{
     76        return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
     77}
     78
    6979/** @}
    7080 */
  • uspace/lib/c/generic/fibril.c

    r2bdf8313 rb0f00a9  
    4141#include <unistd.h>
    4242#include <stdio.h>
    43 #include <arch/barrier.h>
     43#include <libarch/barrier.h>
    4444#include <libarch/faddr.h>
    4545#include <futex.h>
     
    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

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    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_req_0_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_req_1_0(exch, CONSOLE_SET_STYLE, style);
     106        async_exchange_end(exch);
     107}
     108
     109void console_set_color(console_ctrl_t *ctrl, uint8_t bgcolor, uint8_t fgcolor,
    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_req_3_0(exch, CONSOLE_SET_COLOR, bgcolor, fgcolor, flags);
     114        async_exchange_end(exch);
     115}
     116
     117void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t bgcolor,
     118    uint32_t fgcolor)
     119{
     120        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     121        async_req_2_0(exch, CONSOLE_SET_RGB_COLOR, bgcolor, fgcolor);
     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_req_1_0(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_req_2_0(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

    r2bdf8313 rb0f00a9  
    4444#include <io/klog.h>
    4545#include <vfs/vfs.h>
    46 #include <ipc/devmap.h>
     46#include <vfs/vfs_sess.h>
     47#include <ipc/loc.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,
     
    99101static LIST_INITIALIZE(files);
    100102
    101 void __stdio_init(int filc, fdi_node_t *filv[])
     103void __stdio_init(int filc)
    102104{
    103105        if (filc > 0) {
    104                 stdin = fopen_node(filv[0], "r");
     106                stdin = fdopen(0, "r");
    105107        } else {
    106108                stdin = &stdin_null;
     
    109111       
    110112        if (filc > 1) {
    111                 stdout = fopen_node(filv[1], "w");
     113                stdout = fdopen(1, "w");
    112114        } else {
    113115                stdout = &stdout_klog;
     
    116118       
    117119        if (filc > 2) {
    118                 stderr = fopen_node(filv[2], "w");
     120                stderr = fdopen(2, "w");
    119121        } else {
    120122                stderr = &stderr_klog;
     
    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);
     
    286285}
    287286
    288 FILE *fopen_node(fdi_node_t *node, const char *mode)
    289 {
    290         int flags;
    291         if (!parse_mode(mode, &flags))
    292                 return NULL;
    293        
    294         /* Open file. */
    295         FILE *stream = malloc(sizeof(FILE));
    296         if (stream == NULL) {
    297                 errno = ENOMEM;
    298                 return NULL;
    299         }
    300        
    301         stream->fd = open_node(node, flags);
    302         if (stream->fd < 0) {
    303                 /* errno was set by open_node() */
    304                 free(stream);
    305                 return NULL;
    306         }
    307        
    308         stream->error = false;
    309         stream->eof = false;
    310         stream->klog = false;
    311         stream->phone = -1;
    312         stream->need_sync = false;
    313         _setvbuf(stream);
    314        
    315         list_append(&stream->link, &files);
    316        
    317         return stream;
    318 }
    319 
    320287int fclose(FILE *stream)
    321288{
     
    324291        fflush(stream);
    325292       
    326         if (stream->phone >= 0)
    327                 async_hangup(stream->phone);
     293        if (stream->sess != NULL)
     294                async_hangup(stream->sess);
    328295       
    329296        if (stream->fd >= 0)
     
    451418
    452419        bytes_used = stream->buf_head - stream->buf_tail;
    453         if (bytes_used == 0)
    454                 return;
    455420
    456421        /* If buffer has prefetched read data, we need to seek back. */
    457         if (stream->buf_state == _bs_read)
     422        if (bytes_used > 0 && stream->buf_state == _bs_read)
    458423                lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
    459424
    460425        /* If buffer has unwritten data, we need to write them out. */
    461         if (stream->buf_state == _bs_write)
     426        if (bytes_used > 0 && stream->buf_state == _bs_write)
    462427                (void) _fwrite(stream->buf_tail, 1, bytes_used, stream);
    463428
     
    595560                }
    596561               
    597                 buf += now;
     562                data += now;
    598563                stream->buf_head += now;
    599564                buf_free -= now;
    600565                bytes_left -= now;
    601566                total_written += now;
     567                stream->buf_state = _bs_write;
    602568               
    603569                if (buf_free == 0) {
     
    607573                }
    608574        }
    609        
    610         if (total_written > 0)
    611                 stream->buf_state = _bs_write;
    612575
    613576        if (need_flush)
     
    715678off64_t ftell(FILE *stream)
    716679{
     680        _fflushbuf(stream);
    717681        return lseek(stream->fd, 0, SEEK_CUR);
    718682}
     
    732696        }
    733697       
    734         if (stream->fd >= 0 && stream->need_sync) {
     698        if ((stream->fd >= 0) && (stream->need_sync)) {
    735699                /**
    736700                 * Better than syncing always, but probably still not the
     
    770734}
    771735
    772 int fphone(FILE *stream)
     736async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
    773737{
    774738        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;
    782 }
    783 
    784 int fnode(FILE *stream, fdi_node_t *node)
    785 {
    786         if (stream->fd >= 0)
    787                 return fd_node(stream->fd, node);
     739                if (stream->sess == NULL)
     740                        stream->sess = fd_session(mgmt, stream->fd);
     741               
     742                return stream->sess;
     743        }
     744       
     745        return NULL;
     746}
     747
     748int fhandle(FILE *stream, int *handle)
     749{
     750        if (stream->fd >= 0) {
     751                *handle = stream->fd;
     752                return EOK;
     753        }
    788754       
    789755        return ENOENT;
  • uspace/lib/c/generic/io/klog.c

    r2bdf8313 rb0f00a9  
    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/printf_core.c

    r2bdf8313 rb0f00a9  
    7474#define PRINT_NUMBER_BUFFER_SIZE  (64 + 5)
    7575
     76/** Get signed or unsigned integer argument */
     77#define PRINTF_GET_INT_ARGUMENT(type, ap, flags) \
     78        ({ \
     79                unsigned type res; \
     80                \
     81                if ((flags) & __PRINTF_FLAG_SIGNED) { \
     82                        signed type arg = va_arg((ap), signed type); \
     83                        \
     84                        if (arg < 0) { \
     85                                res = -arg; \
     86                                (flags) |= __PRINTF_FLAG_NEGATIVE; \
     87                        } else \
     88                                res = arg; \
     89                } else \
     90                        res = va_arg((ap), unsigned type); \
     91                \
     92                res; \
     93        })
     94
    7695/** Enumeration of possible arguments types.
    7796 */
     
    206225        }
    207226       
    208         return (int) (counter + 1);
     227        return (int) (counter);
    209228}
    210229
     
    244263        }
    245264       
    246         return (int) (counter + 1);
     265        return (int) (counter);
    247266}
    248267
     
    831850                        size_t size;
    832851                        uint64_t number;
     852                       
    833853                        switch (qualifier) {
    834854                        case PrintfQualifierByte:
    835855                                size = sizeof(unsigned char);
    836                                 number = (uint64_t) va_arg(ap, unsigned int);
     856                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    837857                                break;
    838858                        case PrintfQualifierShort:
    839859                                size = sizeof(unsigned short);
    840                                 number = (uint64_t) va_arg(ap, unsigned int);
     860                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    841861                                break;
    842862                        case PrintfQualifierInt:
    843863                                size = sizeof(unsigned int);
    844                                 number = (uint64_t) va_arg(ap, unsigned int);
     864                                number = PRINTF_GET_INT_ARGUMENT(int, ap, flags);
    845865                                break;
    846866                        case PrintfQualifierLong:
    847867                                size = sizeof(unsigned long);
    848                                 number = (uint64_t) va_arg(ap, unsigned long);
     868                                number = PRINTF_GET_INT_ARGUMENT(long, ap, flags);
    849869                                break;
    850870                        case PrintfQualifierLongLong:
    851871                                size = sizeof(unsigned long long);
    852                                 number = (uint64_t) va_arg(ap, unsigned long long);
     872                                number = PRINTF_GET_INT_ARGUMENT(long long, ap, flags);
    853873                                break;
    854874                        case PrintfQualifierPointer:
     
    865885                                counter = -counter;
    866886                                goto out;
    867                         }
    868                        
    869                         if (flags & __PRINTF_FLAG_SIGNED) {
    870                                 if (number & (0x1 << (size * 8 - 1))) {
    871                                         flags |= __PRINTF_FLAG_NEGATIVE;
    872                                        
    873                                         if (size == sizeof(uint64_t)) {
    874                                                 number = -((int64_t) number);
    875                                         } else {
    876                                                 number = ~number;
    877                                                 number &=
    878                                                     ~(0xFFFFFFFFFFFFFFFFll <<
    879                                                     (size * 8));
    880                                                 number++;
    881                                         }
    882                                 }
    883887                        }
    884888                       
  • uspace/lib/c/generic/io/vprintf.c

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    4747#include <futex.h>
    4848#include <fibril.h>
     49#include <macros.h>
    4950
    5051/**
     
    458459        while (!list_empty(&queued_calls)) {
    459460                async_call_t *call =
    460                     list_get_instance(queued_calls.next, async_call_t, list);
     461                    list_get_instance(list_first(&queued_calls), async_call_t, list);
    461462                ipc_callid_t callid =
    462463                    ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data);
     
    511512       
    512513        link_t *item;
    513         for (item = dispatched_calls.next; item != &dispatched_calls;
     514        for (item = dispatched_calls.head.next; item != &dispatched_calls.head;
    514515            item = item->next) {
    515516                async_call_t *call =
     
    611612/** Request callback connection.
    612613 *
    613  * The @a taskhash and @a phonehash identifiers returned
     614 * The @a task_id and @a phonehash identifiers returned
    614615 * by the kernel can be used for connection tracking.
    615616 *
     
    618619 * @param arg2      User defined argument.
    619620 * @param arg3      User defined argument.
    620  * @param taskhash  Opaque identifier of the client task.
     621 * @param task_id   Identifier of the client task.
    621622 * @param phonehash Opaque identifier of the phone that will
    622623 *                  be used for incoming calls.
     
    626627 */
    627628int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    628     sysarg_t *taskhash, sysarg_t *phonehash)
    629 {
    630         return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    631             arg3, NULL, NULL, NULL, taskhash, phonehash);
     629    task_id_t *task_id, sysarg_t *phonehash)
     630{
     631        ipc_call_t data;
     632        int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
     633            IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
     634        if (rc == EOK) {
     635                *task_id = data.in_task_id;
     636                *phonehash = IPC_GET_ARG5(data);
     637        }       
     638        return rc;
     639}
     640
     641/** Request cloned connection.
     642 *
     643 * @param phoneid Phone handle used for contacting the other side.
     644 *
     645 * @return Cloned phone handle on success or a negative error code.
     646 *
     647 */
     648int ipc_connect_me(int phoneid)
     649{
     650        sysarg_t newphid;
     651        int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL,
     652            NULL, NULL, &newphid);
     653        if (res)
     654                return res;
     655       
     656        return newphid;
    632657}
    633658
  • uspace/lib/c/generic/libc.c

    r2bdf8313 rb0f00a9  
    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"
     
    6463        __malloc_init();
    6564        __async_init();
    66         __async_sess_init();
    6765       
    6866        fibril_t *fibril = fibril_setup();
     
    9391                argc = 0;
    9492                argv = NULL;
    95                 __stdio_init(0, NULL);
     93                __stdio_init(0);
    9694        } else {
    9795                argc = __pcb->argc;
    9896                argv = __pcb->argv;
    99                 __stdio_init(__pcb->filc, __pcb->filv);
     97                __stdio_init(__pcb->filc);
    10098                (void) chdir(__pcb->cwd);
    10199        }
  • uspace/lib/c/generic/loader.c

    r2bdf8313 rb0f00a9  
    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
     
    242256 *
    243257 */
    244 int loader_set_files(loader_t *ldr, fdi_node_t *const files[])
    245 {
    246         /*
    247          * Serialize the arguments into a single array. First
    248          * compute size of the buffer needed.
    249          */
    250         fdi_node_t *const *ap = files;
    251         size_t count = 0;
    252         while (*ap != NULL) {
    253                 count++;
    254                 ap++;
    255         }
    256        
    257         fdi_node_t *files_buf;
    258         files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t));
    259         if (files_buf == NULL)
    260                 return ENOMEM;
    261        
    262         /* Fill the buffer */
    263         size_t i;
    264         for (i = 0; i < count; i++)
    265                 files_buf[i] = *files[i];
    266        
     258int loader_set_files(loader_t *ldr, int * const files[])
     259{
    267260        /* 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,
    271             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 */
    282         free(files_buf);
    283        
    284         return EOK;
     261        async_exch_t *exch = async_exchange_begin(ldr->sess);
     262        async_exch_t *vfs_exch = vfs_exchange_begin();
     263       
     264        int i;
     265        for (i = 0; files[i]; i++);
     266
     267        ipc_call_t answer;
     268        aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer);
     269
     270        sysarg_t rc = EOK;
     271       
     272        for (i = 0; files[i]; i++) {
     273                rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i],
     274                    0, vfs_exch);
     275                if (rc != EOK)
     276                        break;
     277        }
     278       
     279        vfs_exchange_end(vfs_exch);
     280        async_exchange_end(exch);
     281
     282        if (rc != EOK) {
     283                async_wait_for(req, NULL);
     284                return (int) rc;
     285        }
     286       
     287        async_wait_for(req, &rc);
     288        return (int) rc;
    285289}
    286290
     
    297301int loader_load_program(loader_t *ldr)
    298302{
    299         return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
     303        async_exch_t *exch = async_exchange_begin(ldr->sess);
     304        int rc = async_req_0_0(exch, LOADER_LOAD);
     305        async_exchange_end(exch);
     306       
     307        return rc;
    300308}
    301309
     
    306314 * the task and its thread is stopped.
    307315 *
    308  * After using this function, no further operations must be performed
    309  * on the loader structure. It should be de-allocated using free().
     316 * After using this function, no further operations can be performed
     317 * on the loader structure and it is deallocated.
    310318 *
    311319 * @param ldr Loader connection structure.
     
    316324int loader_run(loader_t *ldr)
    317325{
    318         int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
     326        async_exch_t *exch = async_exchange_begin(ldr->sess);
     327        int rc = async_req_0_0(exch, LOADER_RUN);
     328        async_exchange_end(exch);
     329       
    319330        if (rc != EOK)
    320331                return rc;
    321332       
    322         async_hangup(ldr->phone_id);
    323         ldr->phone_id = 0;
     333        async_hangup(ldr->sess);
     334        free(ldr);
     335       
    324336        return EOK;
    325337}
     
    327339/** Cancel the loader session.
    328340 *
    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().
     341 * Tell the loader not to load any program and terminate.
     342 * After using this function, no further operations can be performed
     343 * on the loader structure and it is deallocated.
    332344 *
    333345 * @param ldr Loader connection structure.
     
    338350void loader_abort(loader_t *ldr)
    339351{
    340         async_hangup(ldr->phone_id);
    341         ldr->phone_id = 0;
     352        async_hangup(ldr->sess);
     353        free(ldr);
    342354}
    343355
  • uspace/lib/c/generic/malloc.c

    r2bdf8313 rb0f00a9  
    7979        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    8080
     81/** Overhead of each area. */
     82#define AREA_OVERHEAD(size) \
     83        (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
     84
    8185/** Calculate real size of a heap block.
    8286 *
     
    183187
    184188/** Next heap block to examine (next fit algorithm) */
    185 static heap_block_head_t *next = NULL;
     189static heap_block_head_t *next_fit = NULL;
    186190
    187191/** Futex for thread-safe heap manipulation */
     
    194198                if (!(expr)) {\
    195199                        futex_up(&malloc_futex); \
    196                         assert_abort(#expr, __FILE__, STR2(__LINE__)); \
     200                        assert_abort(#expr, __FILE__, __LINE__); \
    197201                } \
    198202        } while (0)
     
    378382       
    379383        /* Eventually try to create a new area */
    380         return area_create(AREA_FIRST_BLOCK_HEAD(size));
     384        return area_create(AREA_OVERHEAD(size));
    381385}
    382386
     
    455459                        /* Update heap area parameters */
    456460                        area->end = end;
    457                        
    458                         /* Update block layout */
    459                         void *last = (void *) last_head;
    460                         size_t excess = (size_t) (area->end - last);
     461                        size_t excess = ((size_t) area->end) - ((size_t) last_head);
    461462                       
    462463                        if (excess > 0) {
     
    467468                                         * create a new free block.
    468469                                         */
    469                                         block_init(last, excess, true, area);
     470                                        block_init((void *) last_head, excess, true, area);
    470471                                } else {
    471472                                        /*
     
    486487        }
    487488       
    488         next = NULL;
     489        next_fit = NULL;
    489490}
    490491
     
    575576                                split_mark(cur, real_size);
    576577                               
    577                                 next = cur;
     578                                next_fit = cur;
    578579                                return addr;
    579580                        } else {
     
    627628                                                split_mark(next_head, real_size);
    628629                                               
    629                                                 next = next_head;
     630                                                next_fit = next_head;
    630631                                                return aligned;
    631632                                        } else {
     
    653654                                                        split_mark(cur, real_size);
    654655                                                       
    655                                                         next = cur;
     656                                                        next_fit = cur;
    656657                                                        return aligned;
    657658                                                }
     
    691692       
    692693        /* Try the next fit approach */
    693         split = next;
     694        split = next_fit;
    694695       
    695696        if (split != NULL) {
     
    847848                       
    848849                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    849                         next = NULL;
     850                        next_fit = NULL;
    850851                } else
    851852                        reloc = true;
     
    872873void free(const void *addr)
    873874{
     875        if (addr == NULL)
     876                return;
     877
    874878        futex_down(&malloc_futex);
    875879       
  • uspace/lib/c/generic/net/icmp_api.c

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    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

    r2bdf8313 rb0f00a9  
    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/packet.c

    r2bdf8313 rb0f00a9  
    3636 */
    3737
     38#include <assert.h>
    3839#include <malloc.h>
    3940#include <mem.h>
     
    4445#include <sys/mman.h>
    4546
    46 #include <adt/generic_field.h>
     47#include <adt/hash_table.h>
    4748#include <net/packet.h>
    4849#include <net/packet_header.h>
    4950
    50 /** Packet map page size. */
    51 #define PACKET_MAP_SIZE 100
    52 
    53 /** Returns the packet map page index.
    54  * @param[in] packet_id The packet identifier.
    55  */
    56 #define PACKET_MAP_PAGE(packet_id)      (((packet_id) - 1) / PACKET_MAP_SIZE)
    57 
    58 /** Returns the packet index in the corresponding packet map page.
    59  *  @param[in] packet_id The packet identifier.
    60  */
    61 #define PACKET_MAP_INDEX(packet_id)     (((packet_id) - 1) % PACKET_MAP_SIZE)
    62 
    63 /** Type definition of the packet map page. */
    64 typedef packet_t *packet_map_t[PACKET_MAP_SIZE];
    65 
    66 /** Packet map.
    67  * Maps packet identifiers to the packet references.
    68  * @see generic_field.h
    69  */
    70 GENERIC_FIELD_DECLARE(gpm, packet_map_t);
     51/** Packet hash table size. */
     52#define PACKET_HASH_TABLE_SIZE  128
    7153
    7254/** Packet map global data. */
     
    7557        fibril_rwlock_t lock;
    7658        /** Packet map. */
    77         gpm_t packet_map;
     59        hash_table_t packet_map;
     60        /** Packet map operations */
     61        hash_table_operations_t operations;
    7862} pm_globals;
    7963
    80 GENERIC_FIELD_IMPLEMENT(gpm, packet_map_t);
     64typedef struct {
     65        link_t link;
     66        packet_t *packet;
     67} pm_entry_t;
     68
     69/**
     70 * Hash function for the packet mapping hash table
     71 */
     72static hash_index_t pm_hash(unsigned long key[])
     73{
     74        return (hash_index_t) key[0] % PACKET_HASH_TABLE_SIZE;
     75}
     76
     77/**
     78 * Key compare function for the packet mapping hash table
     79 */
     80static int pm_compare(unsigned long key[], hash_count_t keys, link_t *link)
     81{
     82        pm_entry_t *entry = list_get_instance(link, pm_entry_t, link);
     83        return entry->packet->packet_id == key[0];
     84}
     85
     86/**
     87 * Remove callback for the packet mapping hash table
     88 */
     89static void pm_remove_callback(link_t *link)
     90{
     91        pm_entry_t *entry = list_get_instance(link, pm_entry_t, link);
     92        free(entry);
     93}
     94
     95/**
     96 * Wrapper used when destroying the whole table
     97 */
     98static void pm_free_wrapper(link_t *link, void *ignored)
     99{
     100        pm_entry_t *entry = list_get_instance(link, pm_entry_t, link);
     101        free(entry);
     102}
     103
    81104
    82105/** Initializes the packet map.
     
    87110int pm_init(void)
    88111{
    89         int rc;
     112        int rc = EOK;
    90113
    91114        fibril_rwlock_initialize(&pm_globals.lock);
    92115       
    93116        fibril_rwlock_write_lock(&pm_globals.lock);
    94         rc = gpm_initialize(&pm_globals.packet_map);
     117       
     118        pm_globals.operations.hash = pm_hash;
     119        pm_globals.operations.compare = pm_compare;
     120        pm_globals.operations.remove_callback = pm_remove_callback;
     121
     122        if (!hash_table_create(&pm_globals.packet_map, PACKET_HASH_TABLE_SIZE, 1,
     123            &pm_globals.operations))
     124                rc = ENOMEM;
     125       
    95126        fibril_rwlock_write_unlock(&pm_globals.lock);
    96127       
     
    100131/** Finds the packet mapping.
    101132 *
    102  * @param[in] packet_id The packet identifier to be found.
    103  * @return              The found packet reference.
    104  * @return              NULL if the mapping does not exist.
     133 * @param[in] packet_id Packet identifier to be found.
     134 *
     135 * @return The found packet reference.
     136 * @return NULL if the mapping does not exist.
     137 *
    105138 */
    106139packet_t *pm_find(packet_id_t packet_id)
    107140{
    108         packet_map_t *map;
    109         packet_t *packet;
    110 
    111141        if (!packet_id)
    112142                return NULL;
    113 
     143       
    114144        fibril_rwlock_read_lock(&pm_globals.lock);
    115         if (packet_id > PACKET_MAP_SIZE * gpm_count(&pm_globals.packet_map)) {
    116                 fibril_rwlock_read_unlock(&pm_globals.lock);
    117                 return NULL;
    118         }
    119         map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet_id));
    120         if (!map) {
    121                 fibril_rwlock_read_unlock(&pm_globals.lock);
    122                 return NULL;
    123         }
    124         packet = (*map) [PACKET_MAP_INDEX(packet_id)];
     145       
     146        unsigned long key = packet_id;
     147        link_t *link = hash_table_find(&pm_globals.packet_map, &key);
     148       
     149        packet_t *packet;
     150        if (link != NULL) {
     151                pm_entry_t *entry =
     152                    hash_table_get_instance(link, pm_entry_t, link);
     153                packet = entry->packet;
     154        } else
     155                packet = NULL;
     156       
    125157        fibril_rwlock_read_unlock(&pm_globals.lock);
    126158        return packet;
     
    129161/** Adds the packet mapping.
    130162 *
    131  * @param[in] packet    The packet to be remembered.
    132  * @return              EOK on success.
    133  * @return              EINVAL if the packet is not valid.
    134  * @return              EINVAL if the packet map is not initialized.
    135  * @return              ENOMEM if there is not enough memory left.
     163 * @param[in] packet Packet to be remembered.
     164 *
     165 * @return EOK on success.
     166 * @return EINVAL if the packet is not valid.
     167 * @return ENOMEM if there is not enough memory left.
     168 *
    136169 */
    137170int pm_add(packet_t *packet)
    138171{
    139         packet_map_t *map;
    140         int rc;
    141 
    142172        if (!packet_is_valid(packet))
    143173                return EINVAL;
    144 
     174       
    145175        fibril_rwlock_write_lock(&pm_globals.lock);
    146 
    147         if (PACKET_MAP_PAGE(packet->packet_id) <
    148             gpm_count(&pm_globals.packet_map)) {
    149                 map = gpm_get_index(&pm_globals.packet_map,
    150                     PACKET_MAP_PAGE(packet->packet_id));
    151         } else {
    152                 do {
    153                         map = (packet_map_t *) malloc(sizeof(packet_map_t));
    154                         if (!map) {
    155                                 fibril_rwlock_write_unlock(&pm_globals.lock);
    156                                 return ENOMEM;
    157                         }
    158                         bzero(map, sizeof(packet_map_t));
    159                         rc = gpm_add(&pm_globals.packet_map, map);
    160                         if (rc < 0) {
    161                                 fibril_rwlock_write_unlock(&pm_globals.lock);
    162                                 free(map);
    163                                 return rc;
    164                         }
    165                 } while (PACKET_MAP_PAGE(packet->packet_id) >=
    166                     gpm_count(&pm_globals.packet_map));
     176       
     177        pm_entry_t *entry = malloc(sizeof(pm_entry_t));
     178        if (entry == NULL) {
     179                fibril_rwlock_write_unlock(&pm_globals.lock);
     180                return ENOMEM;
    167181        }
    168 
    169         (*map) [PACKET_MAP_INDEX(packet->packet_id)] = packet;
     182       
     183        entry->packet = packet;
     184       
     185        unsigned long key = packet->packet_id;
     186        hash_table_insert(&pm_globals.packet_map, &key, &entry->link);
     187       
    170188        fibril_rwlock_write_unlock(&pm_globals.lock);
     189       
    171190        return EOK;
    172191}
    173192
    174 /** Releases the packet map. */
     193/** Remove the packet mapping
     194 *
     195 * @param[in] packet The packet to be removed
     196 *
     197 */
     198void pm_remove(packet_t *packet)
     199{
     200        assert(packet_is_valid(packet));
     201       
     202        fibril_rwlock_write_lock(&pm_globals.lock);
     203       
     204        unsigned long key = packet->packet_id;
     205        hash_table_remove(&pm_globals.packet_map, &key, 1);
     206       
     207        fibril_rwlock_write_unlock(&pm_globals.lock);
     208}
     209
     210/** Release the packet map. */
    175211void pm_destroy(void)
    176212{
    177         int count;
    178         int index;
    179         packet_map_t *map;
    180         packet_t *packet;
    181 
    182213        fibril_rwlock_write_lock(&pm_globals.lock);
    183         count = gpm_count(&pm_globals.packet_map);
    184         while (count > 0) {
    185                 map = gpm_get_index(&pm_globals.packet_map, count - 1);
    186                 for (index = PACKET_MAP_SIZE - 1; index >= 0; --index) {
    187                         packet = (*map)[index];
    188                         if (packet_is_valid(packet))
    189                                 munmap(packet, packet->length);
    190                 }
    191         }
    192         gpm_destroy(&pm_globals.packet_map, free);
    193         /* leave locked */
     214        hash_table_apply(&pm_globals.packet_map, pm_free_wrapper, NULL);
     215        hash_table_destroy(&pm_globals.packet_map);
     216        /* Leave locked */
    194217}
    195218
     
    199222 * The packet is inserted right before the packets of the same order value.
    200223 *
    201  * @param[in,out] first The first packet of the queue. Sets the first packet of
    202  *                      the queue. The original first packet may be shifted by
    203  *                      the new packet.
    204  * @param[in] packet    The packet to be added.
    205  * @param[in] order     The packet order value.
    206  * @param[in] metric    The metric value of the packet.
    207  * @return              EOK on success.
    208  * @return              EINVAL if the first parameter is NULL.
    209  * @return              EINVAL if the packet is not valid.
     224 * @param[in,out] first First packet of the queue. Sets the first
     225 *                      packet of the queue. The original first packet
     226 *                      may be shifted by the new packet.
     227 * @param[in] packet    Packet to be added.
     228 * @param[in] order     Packet order value.
     229 * @param[in] metric    Metric value of the packet.
     230 *
     231 * @return EOK on success.
     232 * @return EINVAL if the first parameter is NULL.
     233 * @return EINVAL if the packet is not valid.
     234 *
    210235 */
    211236int pq_add(packet_t **first, packet_t *packet, size_t order, size_t metric)
    212237{
    213         packet_t *item;
    214 
    215         if (!first || !packet_is_valid(packet))
     238        if ((!first) || (!packet_is_valid(packet)))
    216239                return EINVAL;
    217 
     240       
    218241        pq_set_order(packet, order, metric);
    219242        if (packet_is_valid(*first)) {
    220                 item = * first;
     243                packet_t *cur = *first;
     244               
    221245                do {
    222                         if (item->order < order) {
    223                                 if (item->next) {
    224                                         item = pm_find(item->next);
    225                                 } else {
    226                                         item->next = packet->packet_id;
    227                                         packet->previous = item->packet_id;
     246                        if (cur->order < order) {
     247                                if (cur->next)
     248                                        cur = pm_find(cur->next);
     249                                else {
     250                                        cur->next = packet->packet_id;
     251                                        packet->previous = cur->packet_id;
     252                                       
    228253                                        return EOK;
    229254                                }
    230255                        } else {
    231                                 packet->previous = item->previous;
    232                                 packet->next = item->packet_id;
    233                                 item->previous = packet->packet_id;
    234                                 item = pm_find(packet->previous);
    235                                 if (item)
    236                                         item->next = packet->packet_id;
     256                                packet->previous = cur->previous;
     257                                packet->next = cur->packet_id;
     258                               
     259                                cur->previous = packet->packet_id;
     260                                cur = pm_find(packet->previous);
     261                               
     262                                if (cur)
     263                                        cur->next = packet->packet_id;
    237264                                else
    238265                                        *first = packet;
     266                               
    239267                                return EOK;
    240268                        }
    241                 } while (packet_is_valid(item));
     269                } while (packet_is_valid(cur));
    242270        }
     271       
    243272        *first = packet;
    244273        return EOK;
     
    312341
    313342        next = pm_find(packet->next);
    314         if (next) {
     343        if (next)
    315344                next->previous = packet->previous;
    316                 previous = pm_find(next->previous);
    317                 if (previous)
    318                         previous->next = next->packet_id;
    319         }
     345       
     346        previous = pm_find(packet->previous);
     347        if (previous)
     348                previous->next = packet->next ;
     349       
    320350        packet->previous = 0;
    321351        packet->next = 0;
  • uspace/lib/c/generic/net/socket_client.c

    r2bdf8313 rb0f00a9  
    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/private/async.h

    r2bdf8313 rb0f00a9  
    3636#define LIBC_PRIVATE_ASYNC_H_
    3737
     38#include <async.h>
    3839#include <adt/list.h>
    3940#include <fibril.h>
     41#include <fibril_synch.h>
    4042#include <sys/time.h>
    4143#include <bool.h>
     
    8183extern void __async_init(void);
    8284extern void async_insert_timeout(awaiter_t *);
     85extern void reply_received(void *, int, ipc_call_t *);
    8386
    8487#endif
  • uspace/lib/c/generic/private/io.h

    r2bdf8313 rb0f00a9  
    3636#define LIBC_PRIVATE_IO_H_
    3737
    38 #include <vfs/vfs.h>
    39 
    40 extern void __stdio_init(int filc, fdi_node_t *filv[]);
     38extern void __stdio_init(int);
    4139extern void __stdio_done(void);
    4240
  • uspace/lib/c/generic/private/ns.h

    r2bdf8313 rb0f00a9  
    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/private/stdio.h

    r2bdf8313 rb0f00a9  
    11/*
    2  * Copyright (c) 2006 Ondrej Palkovsky
    3  * Copyright (c) 2008 Martin Decky
     2 * Copyright (c) 2011 Martin Decky
    43 * All rights reserved.
    54 *
     
    2827 */
    2928
    30 /** @defgroup msimfb MSIM text console
    31  * @brief HelenOS MSIM text console.
    32  * @ingroup fbs
     29/** @addtogroup libc
    3330 * @{
    3431 */
     
    3633 */
    3734
     35#ifndef LIBC_PRIVATE_STDIO_H_
     36#define LIBC_PRIVATE_STDIO_H_
     37
     38#include <adt/list.h>
     39#include <stdio.h>
    3840#include <async.h>
    39 #include <libc.h>
    40 #include <sysinfo.h>
    41 #include <as.h>
    42 #include <ddi.h>
    43 #include <errno.h>
    4441
    45 #include "serial_console.h"
    46 #include "msim.h"
     42struct _IO_FILE {
     43        /** Linked list pointer. */
     44        link_t link;
     45       
     46        /** Underlying file descriptor. */
     47        int fd;
     48       
     49        /** Error indicator. */
     50        int error;
     51       
     52        /** End-of-file indicator. */
     53        int eof;
     54       
     55        /** Klog indicator */
     56        int klog;
     57       
     58        /** Session to the file provider */
     59        async_sess_t *sess;
     60       
     61        /**
     62         * Non-zero if the stream needs sync on fflush(). XXX change
     63         * console semantics so that sync is not needed.
     64         */
     65        int need_sync;
     66       
     67        /** Buffering type */
     68        enum _buffer_type btype;
     69       
     70        /** Buffer */
     71        uint8_t *buf;
     72       
     73        /** Buffer size */
     74        size_t buf_size;
     75       
     76        /** Buffer state */
     77        enum _buffer_state buf_state;
     78       
     79        /** Buffer I/O pointer */
     80        uint8_t *buf_head;
     81       
     82        /** Points to end of occupied space when in read mode. */
     83        uint8_t *buf_tail;
     84};
    4785
    48 #define WIDTH 80
    49 #define HEIGHT 24
    50 
    51 static char *virt_addr;
    52 
    53 static void msim_putc(const char c)
    54 {
    55         *virt_addr = c;
    56 }
    57 
    58 int msim_init(void)
    59 {
    60         sysarg_t phys_addr;
    61         if (sysinfo_get_value("fb.address.physical", &phys_addr) != EOK)
    62                 return -1;
    63        
    64         virt_addr = (char *) as_get_mappable_page(1);
    65        
    66         if (physmem_map((void *) phys_addr, virt_addr, 1,
    67             AS_AREA_READ | AS_AREA_WRITE) != 0)
    68                 return -1;
    69        
    70         serial_console_init(msim_putc, WIDTH, HEIGHT);
    71        
    72         async_set_client_connection(serial_client_connection);
    73         return 0;
    74 }
     86#endif
    7587
    7688/** @}
  • uspace/lib/c/generic/private/thread.h

    r2bdf8313 rb0f00a9  
    3636#define LIBC_PRIVATE_THREAD_H_
    3737
    38 #include <kernel/proc/uarg.h>
     38#include <abi/proc/uarg.h>
    3939
    4040extern void __thread_entry(void);
  • uspace/lib/c/generic/rtld/module.c

    r2bdf8313 rb0f00a9  
    3535 */
    3636
     37#include <adt/list.h>
     38#include <elf/elf_load.h>
     39#include <fcntl.h>
     40#include <loader/pcb.h>
    3741#include <stdio.h>
    3842#include <stdlib.h>
    3943#include <unistd.h>
    40 #include <fcntl.h>
    41 #include <adt/list.h>
    42 #include <loader/pcb.h>
    4344
    4445#include <rtld/rtld.h>
     
    4748#include <rtld/rtld_arch.h>
    4849#include <rtld/module.h>
    49 #include <elf_load.h>
    5050
    5151/** (Eagerly) process all relocation tables in a module.
     
    9393module_t *module_find(const char *name)
    9494{
    95         link_t *head = &runtime_env->modules_head;
    96 
    97         link_t *cur;
    9895        module_t *m;
    9996        const char *p, *soname;
     
    110107
    111108        /* Traverse list of all modules. Not extremely fast, but simple */
    112         DPRINTF("head = %p\n", head);
    113         for (cur = head->next; cur != head; cur = cur->next) {
     109        list_foreach(runtime_env->modules, cur) {
    114110                DPRINTF("cur = %p\n", cur);
    115111                m = list_get_instance(cur, module_t, modules_link);
     
    177173
    178174        /* Insert into the list of loaded modules */
    179         list_append(&m->modules_link, &runtime_env->modules_head);
     175        list_append(&m->modules_link, &runtime_env->modules);
    180176
    181177        return m;
     
    249245void modules_process_relocs(module_t *start)
    250246{
    251         link_t *head = &runtime_env->modules_head;
    252 
    253         link_t *cur;
    254         module_t *m;
    255 
    256         for (cur = head->next; cur != head; cur = cur->next) {
     247        module_t *m;
     248
     249        list_foreach(runtime_env->modules, cur) {
    257250                m = list_get_instance(cur, module_t, modules_link);
    258251
     
    268261void modules_untag(void)
    269262{
    270         link_t *head = &runtime_env->modules_head;
    271 
    272         link_t *cur;
    273         module_t *m;
    274 
    275         for (cur = head->next; cur != head; cur = cur->next) {
     263        module_t *m;
     264
     265        list_foreach(runtime_env->modules, cur) {
    276266                m = list_get_instance(cur, module_t, modules_link);
    277267                m->bfs_tag = false;
  • uspace/lib/c/generic/rtld/rtld.c

    r2bdf8313 rb0f00a9  
    4444{
    4545        runtime_env = &rt_env_static;
    46         list_initialize(&runtime_env->modules_head);
     46        list_initialize(&runtime_env->modules);
    4747        runtime_env->next_bias = 0x2000000;
    4848        runtime_env->program = NULL;
  • uspace/lib/c/generic/rtld/symbol.c

    r2bdf8313 rb0f00a9  
    3838#include <stdlib.h>
    3939
     40#include <elf/elf.h>
    4041#include <rtld/rtld.h>
    4142#include <rtld/rtld_debug.h>
    4243#include <rtld/symbol.h>
    43 #include <elf.h>
    4444
    4545/*
     
    118118        module_t *m, *dm;
    119119        elf_symbol_t *sym, *s;
    120         link_t queue_head;
     120        list_t queue;
    121121        size_t i;
    122122
     
    132132
    133133        /* Insert root (the program) into the queue and tag it */
    134         list_initialize(&queue_head);
     134        list_initialize(&queue);
    135135        start->bfs_tag = true;
    136         list_append(&start->queue_link, &queue_head);
     136        list_append(&start->queue_link, &queue);
    137137
    138138        /* If the symbol is found, it will be stored in 'sym' */
     
    140140
    141141        /* While queue is not empty */
    142         while (!list_empty(&queue_head)) {
     142        while (!list_empty(&queue)) {
    143143                /* Pop first element from the queue */
    144                 m = list_get_instance(queue_head.next, module_t, queue_link);
     144                m = list_get_instance(list_first(&queue), module_t, queue_link);
    145145                list_remove(&m->queue_link);
    146146
     
    162162                        if (dm->bfs_tag == false) {
    163163                                dm->bfs_tag = true;
    164                                 list_append(&dm->queue_link, &queue_head);
     164                                list_append(&dm->queue_link, &queue);
    165165                        }
    166166                }
     
    168168
    169169        /* Empty the queue so that we leave it in a clean state */
    170         while (!list_empty(&queue_head))
    171                 list_remove(queue_head.next);
     170        while (!list_empty(&queue))
     171                list_remove(list_first(&queue));
    172172
    173173        if (!sym) {
  • uspace/lib/c/generic/str.c

    r2bdf8313 rb0f00a9  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
     4 * Copyright (c) 2011 Martin Sucha
     5 * Copyright (c) 2011 Oleg Romanenko
    46 * All rights reserved.
    57 *
     
    540542
    541543        dstr_size = str_size(dest);
     544        if (dstr_size >= size)
     545                return;
     546       
    542547        str_cpy(dest + dstr_size, size - dstr_size, src);
     548}
     549
     550/** Convert space-padded ASCII to string.
     551 *
     552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into
     553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces
     554 * (ASCII 0x20). Convert space-padded ascii to string representation.
     555 *
     556 * If the text does not fit into the destination buffer, the function converts
     557 * as many characters as possible and returns EOVERFLOW.
     558 *
     559 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
     560 * converted anyway and invalid characters are replaced with question marks
     561 * (U_SPECIAL) and the function returns EIO.
     562 *
     563 * Regardless of return value upon return @a dest will always be well-formed.
     564 *
     565 * @param dest          Destination buffer
     566 * @param size          Size of destination buffer
     567 * @param src           Space-padded ASCII.
     568 * @param n             Size of the source buffer in bytes.
     569 *
     570 * @return              EOK on success, EOVERFLOW if the text does not fit
     571 *                      destination buffer, EIO if the text contains
     572 *                      non-ASCII bytes.
     573 */
     574int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
     575{
     576        size_t sidx;
     577        size_t didx;
     578        size_t dlast;
     579        uint8_t byte;
     580        int rc;
     581        int result;
     582
     583        /* There must be space for a null terminator in the buffer. */
     584        assert(size > 0);
     585        result = EOK;
     586
     587        didx = 0;
     588        dlast = 0;
     589        for (sidx = 0; sidx < n; ++sidx) {
     590                byte = src[sidx];
     591                if (!ascii_check(byte)) {
     592                        byte = U_SPECIAL;
     593                        result = EIO;
     594                }
     595
     596                rc = chr_encode(byte, dest, &didx, size - 1);
     597                if (rc != EOK) {
     598                        assert(rc == EOVERFLOW);
     599                        dest[didx] = '\0';
     600                        return rc;
     601                }
     602
     603                /* Remember dest index after last non-empty character */
     604                if (byte != 0x20)
     605                        dlast = didx;
     606        }
     607
     608        /* Terminate string after last non-empty character */
     609        dest[dlast] = '\0';
     610        return result;
    543611}
    544612
     
    572640        dest[dest_off] = '\0';
    573641}
     642
     643/** Convert UTF16 string to string.
     644 *
     645 * Convert utf16 string @a src to string. The output is written to the buffer
     646 * specified by @a dest and @a size. @a size must be non-zero and the string
     647 * written will always be well-formed. Surrogate pairs also supported.
     648 *
     649 * @param dest  Destination buffer.
     650 * @param size  Size of the destination buffer.
     651 * @param src   Source utf16 string.
     652 *
     653 * @return EOK, if success, negative otherwise.
     654 */
     655int utf16_to_str(char *dest, size_t size, const uint16_t *src)
     656{
     657        size_t idx = 0, dest_off = 0;
     658        wchar_t ch;
     659        int rc = EOK;
     660
     661        /* There must be space for a null terminator in the buffer. */
     662        assert(size > 0);
     663
     664        while (src[idx]) {
     665                if ((src[idx] & 0xfc00) == 0xd800) {
     666                        if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) {
     667                                ch = 0x10000;
     668                                ch += (src[idx] & 0x03FF) << 10;
     669                                ch += (src[idx + 1] & 0x03FF);
     670                                idx += 2;
     671                        }
     672                        else
     673                                break;
     674                } else {
     675                        ch = src[idx];
     676                        idx++;
     677                }
     678                rc = chr_encode(ch, dest, &dest_off, size - 1);
     679                if (rc != EOK)
     680                        break;
     681        }
     682        dest[dest_off] = '\0';
     683        return rc;
     684}
     685
     686int str_to_utf16(uint16_t *dest, size_t size, const char *src)
     687{
     688        int rc = EOK;
     689        size_t offset = 0;
     690        size_t idx = 0;
     691        wchar_t c;
     692
     693        assert(size > 0);
     694       
     695        while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) {
     696                if (c > 0x10000) {
     697                        if (idx + 2 >= size - 1) {
     698                                rc = EOVERFLOW;
     699                                break;
     700                        }
     701                        c = (c - 0x10000);
     702                        dest[idx] = 0xD800 | (c >> 10);
     703                        dest[idx + 1] = 0xDC00 | (c & 0x3FF);
     704                        idx++;
     705                } else {
     706                         dest[idx] = c;
     707                }
     708
     709                idx++;
     710                if (idx >= size - 1) {
     711                        rc = EOVERFLOW;
     712                        break;
     713                }
     714        }
     715
     716        dest[idx] = '\0';
     717        return rc;
     718}
     719
    574720
    575721/** Convert wide string to new string.
     
    654800}
    655801
     802/** Convert string to wide string.
     803 *
     804 * Convert string @a src to wide string. A new wide NULL-terminated
     805 * string will be allocated on the heap.
     806 *
     807 * @param src   Source string.
     808 */
     809wchar_t *str_to_awstr(const char *str)
     810{
     811        size_t len = str_length(str);
     812       
     813        wchar_t *wstr = calloc(len+1, sizeof(wchar_t));
     814        if (wstr == NULL)
     815                return NULL;
     816       
     817        str_to_wstr(wstr, len + 1, str);
     818        return wstr;
     819}
     820
    656821/** Find first occurence of character in string.
    657822 *
     
    674839       
    675840        return NULL;
     841}
     842
     843/** Removes specified trailing characters from a string.
     844 *
     845 * @param str String to remove from.
     846 * @param ch  Character to remove.
     847 */
     848void str_rtrim(char *str, wchar_t ch)
     849{
     850        size_t off = 0;
     851        size_t pos = 0;
     852        wchar_t c;
     853        bool update_last_chunk = true;
     854        char *last_chunk = NULL;
     855
     856        while ((c = str_decode(str, &off, STR_NO_LIMIT))) {
     857                if (c != ch) {
     858                        update_last_chunk = true;
     859                        last_chunk = NULL;
     860                } else if (update_last_chunk) {
     861                        update_last_chunk = false;
     862                        last_chunk = (str + pos);
     863                }
     864                pos = off;
     865        }
     866
     867        if (last_chunk)
     868                *last_chunk = '\0';
     869}
     870
     871/** Removes specified leading characters from a string.
     872 *
     873 * @param str String to remove from.
     874 * @param ch  Character to remove.
     875 */
     876void str_ltrim(char *str, wchar_t ch)
     877{
     878        wchar_t acc;
     879        size_t off = 0;
     880        size_t pos = 0;
     881        size_t str_sz = str_size(str);
     882
     883        while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
     884                if (acc != ch)
     885                        break;
     886                else
     887                        pos = off;
     888        }
     889
     890        if (pos > 0) {
     891                memmove(str, &str[pos], str_sz - pos);
     892                pos = str_sz - pos;
     893                str[str_sz - pos] = '\0';
     894        }
    676895}
    677896
     
    9501169        return dest;
    9511170}
    952 
    9531171
    9541172/** Convert initial part of string to unsigned long according to given base.
     
    11271345}
    11281346
     1347/** Convert string to uint8_t.
     1348 *
     1349 * @param nptr   Pointer to string.
     1350 * @param endptr If not NULL, pointer to the first invalid character
     1351 *               is stored here.
     1352 * @param base   Zero or number between 2 and 36 inclusive.
     1353 * @param strict Do not allow any trailing characters.
     1354 * @param result Result of the conversion.
     1355 *
     1356 * @return EOK if conversion was successful.
     1357 *
     1358 */
     1359int str_uint8_t(const char *nptr, char **endptr, unsigned int base,
     1360    bool strict, uint8_t *result)
     1361{
     1362        assert(result != NULL);
     1363       
     1364        bool neg;
     1365        char *lendptr;
     1366        uint64_t res;
     1367        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1368       
     1369        if (endptr != NULL)
     1370                *endptr = (char *) lendptr;
     1371       
     1372        if (ret != EOK)
     1373                return ret;
     1374       
     1375        /* Do not allow negative values */
     1376        if (neg)
     1377                return EINVAL;
     1378       
     1379        /* Check whether we are at the end of
     1380           the string in strict mode */
     1381        if ((strict) && (*lendptr != 0))
     1382                return EINVAL;
     1383       
     1384        /* Check for overflow */
     1385        uint8_t _res = (uint8_t) res;
     1386        if (_res != res)
     1387                return EOVERFLOW;
     1388       
     1389        *result = _res;
     1390       
     1391        return EOK;
     1392}
     1393
     1394/** Convert string to uint16_t.
     1395 *
     1396 * @param nptr   Pointer to string.
     1397 * @param endptr If not NULL, pointer to the first invalid character
     1398 *               is stored here.
     1399 * @param base   Zero or number between 2 and 36 inclusive.
     1400 * @param strict Do not allow any trailing characters.
     1401 * @param result Result of the conversion.
     1402 *
     1403 * @return EOK if conversion was successful.
     1404 *
     1405 */
     1406int str_uint16_t(const char *nptr, char **endptr, unsigned int base,
     1407    bool strict, uint16_t *result)
     1408{
     1409        assert(result != NULL);
     1410       
     1411        bool neg;
     1412        char *lendptr;
     1413        uint64_t res;
     1414        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1415       
     1416        if (endptr != NULL)
     1417                *endptr = (char *) lendptr;
     1418       
     1419        if (ret != EOK)
     1420                return ret;
     1421       
     1422        /* Do not allow negative values */
     1423        if (neg)
     1424                return EINVAL;
     1425       
     1426        /* Check whether we are at the end of
     1427           the string in strict mode */
     1428        if ((strict) && (*lendptr != 0))
     1429                return EINVAL;
     1430       
     1431        /* Check for overflow */
     1432        uint16_t _res = (uint16_t) res;
     1433        if (_res != res)
     1434                return EOVERFLOW;
     1435       
     1436        *result = _res;
     1437       
     1438        return EOK;
     1439}
     1440
     1441/** Convert string to uint32_t.
     1442 *
     1443 * @param nptr   Pointer to string.
     1444 * @param endptr If not NULL, pointer to the first invalid character
     1445 *               is stored here.
     1446 * @param base   Zero or number between 2 and 36 inclusive.
     1447 * @param strict Do not allow any trailing characters.
     1448 * @param result Result of the conversion.
     1449 *
     1450 * @return EOK if conversion was successful.
     1451 *
     1452 */
     1453int str_uint32_t(const char *nptr, char **endptr, unsigned int base,
     1454    bool strict, uint32_t *result)
     1455{
     1456        assert(result != NULL);
     1457       
     1458        bool neg;
     1459        char *lendptr;
     1460        uint64_t res;
     1461        int ret = str_uint(nptr, &lendptr, base, &neg, &res);
     1462       
     1463        if (endptr != NULL)
     1464                *endptr = (char *) lendptr;
     1465       
     1466        if (ret != EOK)
     1467                return ret;
     1468       
     1469        /* Do not allow negative values */
     1470        if (neg)
     1471                return EINVAL;
     1472       
     1473        /* Check whether we are at the end of
     1474           the string in strict mode */
     1475        if ((strict) && (*lendptr != 0))
     1476                return EINVAL;
     1477       
     1478        /* Check for overflow */
     1479        uint32_t _res = (uint32_t) res;
     1480        if (_res != res)
     1481                return EOVERFLOW;
     1482       
     1483        *result = _res;
     1484       
     1485        return EOK;
     1486}
     1487
    11291488/** Convert string to uint64_t.
    11301489 *
  • uspace/lib/c/generic/str_error.c

    r2bdf8313 rb0f00a9  
    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/sysinfo.c

    r2bdf8313 rb0f00a9  
    4747 *
    4848 */
    49 sysinfo_item_tag_t sysinfo_get_tag(const char *path)
     49sysinfo_item_val_type_t sysinfo_get_val_type(const char *path)
    5050{
    51         return (sysinfo_item_tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,
     51        return (sysinfo_item_val_type_t) __SYSCALL2(SYS_SYSINFO_GET_VAL_TYPE,
    5252            (sysarg_t) path, (sysarg_t) str_size(path));
    5353}
  • uspace/lib/c/generic/task.c

    r2bdf8313 rb0f00a9  
    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"
     48#include <vfs/vfs.h>
    4649
    4750task_id_t task_get_id(void)
     
    6871int task_set_name(const char *name)
    6972{
     73        assert(name);
     74       
    7075        return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name));
    7176}
     
    8893 * loader API. Arguments are passed as a null-terminated array of strings.
    8994 *
    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.
     95 * @param id   If not NULL, the ID of the task is stored here on success.
     96 * @param path Pathname of the binary to execute.
     97 * @param argv Command-line arguments.
     98 *
     99 * @return Zero on success or negative error code.
     100 *
    95101 */
    96102int task_spawnv(task_id_t *id, const char *path, const char *const args[])
    97103{
    98         loader_t *ldr;
    99         task_id_t task_id;
    100         int rc;
    101 
     104        /* Send default files */
     105        int *files[4];
     106        int fd_stdin;
     107        int fd_stdout;
     108        int fd_stderr;
     109       
     110        if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK))
     111                files[0] = &fd_stdin;
     112        else
     113                files[0] = NULL;
     114       
     115        if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK))
     116                files[1] = &fd_stdout;
     117        else
     118                files[1] = NULL;
     119       
     120        if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK))
     121                files[2] = &fd_stderr;
     122        else
     123                files[2] = NULL;
     124       
     125        files[3] = NULL;
     126       
     127        return task_spawnvf(id, path, args, files);
     128}
     129
     130/** Create a new task by running an executable from the filesystem.
     131 *
     132 * This is really just a convenience wrapper over the more complicated
     133 * loader API. Arguments are passed as a null-terminated array of strings.
     134 * Files are passed as null-terminated array of pointers to fdi_node_t.
     135 *
     136 * @param id    If not NULL, the ID of the task is stored here on success.
     137 * @param path  Pathname of the binary to execute.
     138 * @param argv  Command-line arguments.
     139 * @param files Standard files to use.
     140 *
     141 * @return Zero on success or negative error code.
     142 *
     143 */
     144int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
     145    int *const files[])
     146{
    102147        /* Connect to a program loader. */
    103         ldr = loader_connect();
     148        loader_t *ldr = loader_connect();
    104149        if (ldr == NULL)
    105150                return EREFUSED;
    106151       
    107152        /* Get task ID. */
    108         rc = loader_get_task_id(ldr, &task_id);
     153        task_id_t task_id;
     154        int rc = loader_get_task_id(ldr, &task_id);
    109155        if (rc != EOK)
    110156                goto error;
     
    125171                goto error;
    126172       
    127         /* Send default files */
    128         fdi_node_t *files[4];
    129         fdi_node_t stdin_node;
    130         fdi_node_t stdout_node;
    131         fdi_node_t stderr_node;
    132        
    133         if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
    134                 files[0] = &stdin_node;
    135         else
    136                 files[0] = NULL;
    137        
    138         if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
    139                 files[1] = &stdout_node;
    140         else
    141                 files[1] = NULL;
    142        
    143         if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
    144                 files[2] = &stderr_node;
    145         else
    146                 files[2] = NULL;
    147        
    148         files[3] = NULL;
    149        
     173        /* Send files */
    150174        rc = loader_set_files(ldr, files);
    151175        if (rc != EOK)
     
    163187       
    164188        /* Success */
    165         free(ldr);
    166        
    167189        if (id != NULL)
    168190                *id = task_id;
     
    173195        /* Error exit */
    174196        loader_abort(ldr);
    175         free(ldr);
    176197        return rc;
    177198}
     
    182203 * loader API. Arguments are passed as a null-terminated list of arguments.
    183204 *
    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.
     205 * @param id   If not NULL, the ID of the task is stored here on success.
     206 * @param path Pathname of the binary to execute.
     207 * @param ...  Command-line arguments.
     208 *
     209 * @return Zero on success or negative error code.
     210 *
    189211 */
    190212int task_spawnl(task_id_t *task_id, const char *path, ...)
    191213{
     214        /* Count the number of arguments. */
     215       
    192216        va_list ap;
    193         int rc, cnt;
    194217        const char *arg;
    195218        const char **arglist;
    196 
    197         /* Count the number of arguments. */
    198         cnt = 0;
     219        int cnt = 0;
     220       
    199221        va_start(ap, path);
    200222        do {
     
    203225        } while (arg != NULL);
    204226        va_end(ap);
    205 
     227       
    206228        /* Allocate argument list. */
    207229        arglist = malloc(cnt * sizeof(const char *));
    208230        if (arglist == NULL)
    209231                return ENOMEM;
    210 
     232       
    211233        /* Fill in arguments. */
    212234        cnt = 0;
     
    217239        } while (arg != NULL);
    218240        va_end(ap);
    219 
     241       
    220242        /* Spawn task. */
    221         rc = task_spawnv(task_id, path, arglist);
    222 
     243        int rc = task_spawnv(task_id, path, arglist);
     244       
    223245        /* Free argument list. */
    224246        free(arglist);
     
    228250int task_wait(task_id_t id, task_exit_t *texit, int *retval)
    229251{
     252        assert(texit);
     253        assert(retval);
     254       
     255        async_exch_t *exch = async_exchange_begin(session_ns);
    230256        sysarg_t te, rv;
    231         int rc;
    232 
    233         rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
     257        int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id),
    234258            UPPER32(id), &te, &rv);
     259        async_exchange_end(exch);
     260       
    235261        *texit = te;
    236262        *retval = rv;
    237 
     263       
    238264        return rc;
    239265}
     
    241267int task_retval(int val)
    242268{
    243         return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
     269        async_exch_t *exch = async_exchange_begin(session_ns);
     270        int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
     271        async_exchange_end(exch);
     272       
     273        return rc;
    244274}
    245275
  • uspace/lib/c/generic/thread.c

    r2bdf8313 rb0f00a9  
    3737#include <stdlib.h>
    3838#include <libarch/faddr.h>
    39 #include <kernel/proc/uarg.h>
     39#include <abi/proc/uarg.h>
    4040#include <fibril.h>
    4141#include <str.h>
     
    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

    r2bdf8313 rb0f00a9  
    3636#include <time.h>
    3737#include <bool.h>
    38 #include <arch/barrier.h>
     38#include <libarch/barrier.h>
    3939#include <macros.h>
    4040#include <errno.h>
     
    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

    r2bdf8313 rb0f00a9  
    3535#include <udebug.h>
    3636#include <sys/types.h>
     37#include <abi/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

    r2bdf8313 rb0f00a9  
    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>
     
    5051#include <assert.h>
    5152#include <str.h>
    52 #include <devmap.h>
     53#include <loc.h>
    5354#include <ipc/vfs.h>
    54 #include <ipc/devmap.h>
    55 
    56 static async_sess_t vfs_session;
    57 
    58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    59 static int vfs_phone = -1;
     55#include <ipc/loc.h>
     56
     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 */
     71async_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 */
     89void 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 
    152 int mount(const char *fs_name, const char *mp, const char *fqdn,
    153     const char *opts, unsigned int flags)
     144int mount(const char *fs_name, const char *mp, const char *fqsn,
     145    const char *opts, unsigned int flags, unsigned int instance)
    154146{
    155147        int null_id = -1;
    156         char null[DEVMAP_NAME_MAXLEN];
    157        
    158         if (str_cmp(fqdn, "") == 0) {
     148        char null[LOC_NAME_MAXLEN];
     149       
     150        if (str_cmp(fqsn, "") == 0) {
    159151                /* No device specified, create a fresh
    160152                   null/%d device instead */
    161                 null_id = devmap_null_create();
     153                null_id = loc_null_create();
    162154               
    163155                if (null_id == -1)
    164156                        return ENOMEM;
    165157               
    166                 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
    167                 fqdn = null;
    168         }
    169        
    170         devmap_handle_t devmap_handle;
    171         int res = devmap_device_get_handle(fqdn, &devmap_handle, flags);
     158                snprintf(null, LOC_NAME_MAXLEN, "null/%d", null_id);
     159                fqsn = null;
     160        }
     161       
     162        service_id_t service_id;
     163        int res = loc_service_get_id(fqsn, &service_id, flags);
    172164        if (res != EOK) {
    173165                if (null_id != -1)
    174                         devmap_null_destroy(null_id);
     166                        loc_null_destroy(null_id);
    175167               
    176168                return res;
     
    181173        if (!mpa) {
    182174                if (null_id != -1)
    183                         devmap_null_destroy(null_id);
     175                        loc_null_destroy(null_id);
    184176               
    185177                return ENOMEM;
    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_3(exch, VFS_IN_MOUNT, service_id, flags,
     184            instance, NULL);
     185        sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     186        if (rc != EOK) {
     187                vfs_exchange_end(exch);
    195188                free(mpa);
    196189                async_wait_for(req, &rc_orig);
    197190               
    198191                if (null_id != -1)
    199                         devmap_null_destroy(null_id);
    200                
    201                 if (rc_orig == EOK)
    202                         return (int) rc;
    203                 else
    204                         return (int) rc_orig;
    205         }
    206        
    207         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    208         if (rc != EOK) {
    209                 vfs_exchange_end(vfs_phone);
     192                        loc_null_destroy(null_id);
     193               
     194                if (rc_orig == EOK)
     195                        return (int) rc;
     196                else
     197                        return (int) rc_orig;
     198        }
     199       
     200        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     201        if (rc != EOK) {
     202                vfs_exchange_end(exch);
    210203                free(mpa);
    211204                async_wait_for(req, &rc_orig);
    212205               
    213206                if (null_id != -1)
    214                         devmap_null_destroy(null_id);
    215                
    216                 if (rc_orig == EOK)
    217                         return (int) rc;
    218                 else
    219                         return (int) rc_orig;
    220         }
    221        
    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);
     207                        loc_null_destroy(null_id);
     208               
     209                if (rc_orig == EOK)
     210                        return (int) rc;
     211                else
     212                        return (int) rc_orig;
     213        }
     214       
     215        rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
     216        if (rc != EOK) {
     217                vfs_exchange_end(exch);
    225218                free(mpa);
    226219                async_wait_for(req, &rc_orig);
    227220               
    228221                if (null_id != -1)
    229                         devmap_null_destroy(null_id);
     222                        loc_null_destroy(null_id);
    230223               
    231224                if (rc_orig == EOK)
     
    236229       
    237230        /* 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);
     231        rc = async_req_0_0(exch, VFS_IN_PING);
     232        if (rc != EOK) {
     233                vfs_exchange_end(exch);
    241234                free(mpa);
    242235                async_wait_for(req, &rc_orig);
    243236               
    244237                if (null_id != -1)
    245                         devmap_null_destroy(null_id);
    246                
    247                 if (rc_orig == EOK)
    248                         return (int) rc;
    249                 else
    250                         return (int) rc_orig;
    251         }
    252        
    253         vfs_exchange_end(vfs_phone);
     238                        loc_null_destroy(null_id);
     239               
     240                if (rc_orig == EOK)
     241                        return (int) rc;
     242                else
     243                        return (int) rc_orig;
     244        }
     245       
     246        vfs_exchange_end(exch);
    254247        free(mpa);
    255248        async_wait_for(req, &rc);
    256249       
    257250        if ((rc != EOK) && (null_id != -1))
    258                 devmap_null_destroy(null_id);
     251                loc_null_destroy(null_id);
    259252       
    260253        return (int) rc;
     
    273266                return ENOMEM;
    274267       
    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);
     268        async_exch_t *exch = vfs_exchange_begin();
     269       
     270        req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
     271        rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     272        if (rc != EOK) {
     273                vfs_exchange_end(exch);
    281274                free(mpa);
    282275                async_wait_for(req, &rc_orig);
     
    288281       
    289282
    290         vfs_exchange_end(vfs_phone);
     283        vfs_exchange_end(exch);
    291284        free(mpa);
    292285        async_wait_for(req, &rc);
     
    297290static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    298291{
    299         int vfs_phone = vfs_exchange_begin();
     292        async_exch_t *exch = vfs_exchange_begin();
    300293       
    301294        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);
     295        aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     296        sysarg_t rc = async_data_write_start(exch, abs, abs_size);
     297       
     298        if (rc != EOK) {
     299                vfs_exchange_end(exch);
    307300
    308301                sysarg_t rc_orig;
     
    315308        }
    316309       
    317         vfs_exchange_end(vfs_phone);
     310        vfs_exchange_end(exch);
    318311        async_wait_for(req, &rc);
    319312       
     
    337330}
    338331
    339 int open_node(fdi_node_t *node, int oflag)
    340 {
    341         int vfs_phone = vfs_exchange_begin();
    342        
    343         ipc_call_t answer;
    344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
    345             node->devmap_handle, node->index, oflag, &answer);
    346        
    347         vfs_exchange_end(vfs_phone);
    348 
    349         sysarg_t rc;
    350         async_wait_for(req, &rc);
    351        
    352         if (rc != EOK)
    353                 return (int) rc;
    354        
    355         return (int) IPC_GET_ARG1(answer);
    356 }
    357 
    358332int close(int fildes)
    359333{
    360334        sysarg_t rc;
    361335       
    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;
     336        async_exch_t *exch = vfs_exchange_begin();
     337        rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
     338        vfs_exchange_end(exch);
     339       
     340        return (int) rc;
    369341}
    370342
     
    374346        ipc_call_t answer;
    375347        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);
     348       
     349        async_exch_t *exch = vfs_exchange_begin();
     350       
     351        req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
     352        rc = async_data_read_start(exch, (void *)buf, nbyte);
     353        if (rc != EOK) {
     354                vfs_exchange_end(exch);
    384355
    385356                sysarg_t rc_orig;
     
    391362                        return (ssize_t) rc_orig;
    392363        }
    393         vfs_exchange_end(vfs_phone);
     364        vfs_exchange_end(exch);
    394365        async_wait_for(req, &rc);
    395366        if (rc == EOK)
     
    404375        ipc_call_t answer;
    405376        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);
     377       
     378        async_exch_t *exch = vfs_exchange_begin();
     379       
     380        req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
     381        rc = async_data_write_start(exch, (void *)buf, nbyte);
     382        if (rc != EOK) {
     383                vfs_exchange_end(exch);
    414384
    415385                sysarg_t rc_orig;
     
    421391                        return (ssize_t) rc_orig;
    422392        }
    423         vfs_exchange_end(vfs_phone);
     393        vfs_exchange_end(exch);
    424394        async_wait_for(req, &rc);
    425395        if (rc == EOK)
     
    429399}
    430400
     401/** Read entire buffer.
     402 *
     403 * In face of short reads this function continues reading until either
     404 * the entire buffer is read or no more data is available (at end of file).
     405 *
     406 * @param fildes        File descriptor
     407 * @param buf           Buffer, @a nbytes bytes long
     408 * @param nbytes        Number of bytes to read
     409 *
     410 * @return              On success, positive number of bytes read.
     411 *                      On failure, negative error code from read().
     412 */
     413ssize_t read_all(int fildes, void *buf, size_t nbyte)
     414{
     415        ssize_t cnt = 0;
     416        size_t nread = 0;
     417        uint8_t *bp = (uint8_t *) buf;
     418
     419        do {
     420                bp += cnt;
     421                nread += cnt;
     422                cnt = read(fildes, bp, nbyte - nread);
     423        } while (cnt > 0 && (nbyte - nread - cnt) > 0);
     424
     425        if (cnt < 0)
     426                return cnt;
     427
     428        return nread + cnt;
     429}
     430
     431/** Write entire buffer.
     432 *
     433 * This function fails if it cannot write exactly @a len bytes to the file.
     434 *
     435 * @param fildes        File descriptor
     436 * @param buf           Data, @a nbytes bytes long
     437 * @param nbytes        Number of bytes to write
     438 *
     439 * @return              EOK on error, return value from write() if writing
     440 *                      failed.
     441 */
     442ssize_t write_all(int fildes, const void *buf, size_t nbyte)
     443{
     444        ssize_t cnt = 0;
     445        ssize_t nwritten = 0;
     446        const uint8_t *bp = (uint8_t *) buf;
     447
     448        do {
     449                bp += cnt;
     450                nwritten += cnt;
     451                cnt = write(fildes, bp, nbyte - nwritten);
     452        } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
     453
     454        if (cnt < 0)
     455                return cnt;
     456
     457        if ((ssize_t)nbyte - nwritten - cnt > 0)
     458                return EIO;
     459
     460        return nbyte;
     461}
     462
    431463int fsync(int fildes)
    432464{
    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);
     465        async_exch_t *exch = vfs_exchange_begin();
     466        sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
     467        vfs_exchange_end(exch);
    438468       
    439469        return (int) rc;
     
    442472off64_t lseek(int fildes, off64_t offset, int whence)
    443473{
    444         int vfs_phone = vfs_exchange_begin();
     474        async_exch_t *exch = vfs_exchange_begin();
    445475       
    446476        sysarg_t newoff_lo;
    447477        sysarg_t newoff_hi;
    448         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     478        sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
    449479            LOWER32(offset), UPPER32(offset), whence,
    450480            &newoff_lo, &newoff_hi);
    451481       
    452         vfs_exchange_end(vfs_phone);
     482        vfs_exchange_end(exch);
    453483       
    454484        if (rc != EOK)
     
    462492        sysarg_t rc;
    463493       
    464         int vfs_phone = vfs_exchange_begin();
    465        
    466         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     494        async_exch_t *exch = vfs_exchange_begin();
     495        rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
    467496            LOWER32(length), UPPER32(length));
    468         vfs_exchange_end(vfs_phone);
     497        vfs_exchange_end(exch);
    469498       
    470499        return (int) rc;
     
    475504        sysarg_t rc;
    476505        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);
     506       
     507        async_exch_t *exch = vfs_exchange_begin();
     508       
     509        req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
     510        rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
     511        if (rc != EOK) {
     512                vfs_exchange_end(exch);
    484513
    485514                sysarg_t rc_orig;
     
    491520                        return (ssize_t) rc_orig;
    492521        }
    493         vfs_exchange_end(vfs_phone);
     522        vfs_exchange_end(exch);
    494523        async_wait_for(req, &rc);
    495524
     
    508537                return ENOMEM;
    509538       
    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);
     539        async_exch_t *exch = vfs_exchange_begin();
     540       
     541        req = async_send_0(exch, VFS_IN_STAT, NULL);
     542        rc = async_data_write_start(exch, pa, pa_size);
     543        if (rc != EOK) {
     544                vfs_exchange_end(exch);
    516545                free(pa);
    517546                async_wait_for(req, &rc_orig);
     
    521550                        return (int) rc_orig;
    522551        }
    523         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    524         if (rc != EOK) {
    525                 vfs_exchange_end(vfs_phone);
     552        rc = async_data_read_start(exch, stat, sizeof(struct stat));
     553        if (rc != EOK) {
     554                vfs_exchange_end(exch);
    526555                free(pa);
    527556                async_wait_for(req, &rc_orig);
     
    531560                        return (int) rc_orig;
    532561        }
    533         vfs_exchange_end(vfs_phone);
     562        vfs_exchange_end(exch);
    534563        free(pa);
    535564        async_wait_for(req, &rc);
     
    592621                return ENOMEM;
    593622       
    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);
     623        async_exch_t *exch = vfs_exchange_begin();
     624       
     625        req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
     626        rc = async_data_write_start(exch, pa, pa_size);
     627        if (rc != EOK) {
     628                vfs_exchange_end(exch);
    600629                free(pa);
    601630
     
    608637                        return (int) rc_orig;
    609638        }
    610         vfs_exchange_end(vfs_phone);
     639        vfs_exchange_end(exch);
    611640        free(pa);
    612641        async_wait_for(req, &rc);
     
    623652        if (!pa)
    624653                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);
     654       
     655        async_exch_t *exch = vfs_exchange_begin();
     656       
     657        req = async_send_1(exch, VFS_IN_UNLINK, lflag, NULL);
     658        rc = async_data_write_start(exch, pa, pa_size);
     659        if (rc != EOK) {
     660                vfs_exchange_end(exch);
    632661                free(pa);
    633662
     
    640669                        return (int) rc_orig;
    641670        }
    642         vfs_exchange_end(vfs_phone);
     671        vfs_exchange_end(exch);
    643672        free(pa);
    644673        async_wait_for(req, &rc);
     
    673702                return ENOMEM;
    674703        }
    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);
     704       
     705        async_exch_t *exch = vfs_exchange_begin();
     706       
     707        req = async_send_0(exch, VFS_IN_RENAME, NULL);
     708        rc = async_data_write_start(exch, olda, olda_size);
     709        if (rc != EOK) {
     710                vfs_exchange_end(exch);
    682711                free(olda);
    683712                free(newa);
     
    688717                        return (int) rc_orig;
    689718        }
    690         rc = async_data_write_start(vfs_phone, newa, newa_size);
    691         if (rc != EOK) {
    692                 vfs_exchange_end(vfs_phone);
     719        rc = async_data_write_start(exch, newa, newa_size);
     720        if (rc != EOK) {
     721                vfs_exchange_end(exch);
    693722                free(olda);
    694723                free(newa);
     
    699728                        return (int) rc_orig;
    700729        }
    701         vfs_exchange_end(vfs_phone);
     730        vfs_exchange_end(exch);
    702731        free(olda);
    703732        free(newa);
     
    755784}
    756785
    757 int fd_phone(int fildes)
     786async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
    758787{
    759788        struct stat stat;
    760        
    761789        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);
    769 }
    770 
    771 int fd_node(int fildes, fdi_node_t *node)
    772 {
    773         struct stat stat;
    774         int rc;
    775 
    776         rc = fstat(fildes, &stat);
    777        
    778         if (rc == EOK) {
    779                 node->fs_handle = stat.fs_handle;
    780                 node->devmap_handle = stat.devmap_handle;
    781                 node->index = stat.index;
    782         }
    783        
    784         return rc;
     790        if (rc != 0) {
     791                errno = rc;
     792                return NULL;
     793        }
     794       
     795        if (!stat.service) {
     796                errno = ENOENT;
     797                return NULL;
     798        }
     799       
     800        return loc_service_connect(mgmt, stat.service, 0);
    785801}
    786802
    787803int dup2(int oldfd, int newfd)
    788804{
    789         int vfs_phone = vfs_exchange_begin();
     805        async_exch_t *exch = vfs_exchange_begin();
    790806       
    791807        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);
     808        sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
     809       
     810        vfs_exchange_end(exch);
    795811       
    796812        if (rc == EOK)
     
    800816}
    801817
     818int fd_wait(void)
     819{
     820        async_exch_t *exch = vfs_exchange_begin();
     821       
     822        sysarg_t ret;
     823        sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret);
     824       
     825        vfs_exchange_end(exch);
     826       
     827        if (rc == EOK)
     828                return (int) ret;
     829       
     830        return (int) rc;
     831}
     832
     833int get_mtab_list(list_t *mtab_list)
     834{
     835        sysarg_t rc;
     836        aid_t req;
     837        size_t i;
     838        sysarg_t num_mounted_fs;
     839       
     840        async_exch_t *exch = vfs_exchange_begin();
     841
     842        req = async_send_0(exch, VFS_IN_MTAB_GET, NULL);
     843
     844        /* Ask VFS how many filesystems are mounted */
     845        rc = async_req_0_1(exch, VFS_IN_PING, &num_mounted_fs);
     846        if (rc != EOK)
     847                goto exit;
     848
     849        for (i = 0; i < num_mounted_fs; ++i) {
     850                mtab_ent_t *mtab_ent;
     851
     852                mtab_ent = malloc(sizeof(mtab_ent_t));
     853                if (!mtab_ent) {
     854                        rc = ENOMEM;
     855                        goto exit;
     856                }
     857
     858                memset(mtab_ent, 0, sizeof(mtab_ent_t));
     859
     860                rc = async_data_read_start(exch, (void *) mtab_ent->mp,
     861                    MAX_PATH_LEN);
     862                if (rc != EOK)
     863                        goto exit;
     864
     865                rc = async_data_read_start(exch, (void *) mtab_ent->opts,
     866                        MAX_MNTOPTS_LEN);
     867                if (rc != EOK)
     868                        goto exit;
     869
     870                rc = async_data_read_start(exch, (void *) mtab_ent->fs_name,
     871                        FS_NAME_MAXLEN);
     872                if (rc != EOK)
     873                        goto exit;
     874
     875                sysarg_t p[2];
     876
     877                rc = async_req_0_2(exch, VFS_IN_PING, &p[0], &p[1]);
     878                if (rc != EOK)
     879                        goto exit;
     880
     881                mtab_ent->instance = p[0];
     882                mtab_ent->service_id = p[1];
     883
     884                link_initialize(&mtab_ent->link);
     885                list_append(&mtab_ent->link, mtab_list);
     886        }
     887
     888exit:
     889        async_wait_for(req, &rc);
     890        vfs_exchange_end(exch);
     891        return rc;
     892}
     893
    802894/** @}
    803895 */
Note: See TracChangeset for help on using the changeset viewer.