Changeset 6ec1d48 in mainline for uspace/lib/hound/src/protocol.c


Ignore:
Timestamp:
2013-03-24T18:28:45Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5bf4310
Parents:
e6e5f4e
Message:

libhound: Implement server side connection controls

Fix lockup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/hound/src/protocol.c

    re6e5f4e r6ec1d48  
    3737#include <errno.h>
    3838#include <loc.h>
     39#include <macros.h>
    3940#include <str.h>
    4041#include <stdlib.h>
     
    143144        }
    144145        unsigned name_count = IPC_GET_ARG1(res_call);
    145         size_t max_length = IPC_GET_ARG2(res_call);
    146146
    147147        /* Start receiving names */
    148         const char ** names = NULL;
     148        const char **names = NULL;
    149149        if (name_count) {
     150                size_t *sizes = calloc(name_count, sizeof(size_t));
    150151                names = calloc(name_count, sizeof(char *));
    151                 char *tmp_name = malloc(max_length + 1);
    152                 if (!names || !tmp_name) {
    153                         async_exchange_end(exch);
    154                         return ENOMEM;
    155                 }
    156                 for (unsigned i = 0; i < name_count; ++i) {
    157                         bzero(tmp_name, max_length + 1);
    158                         ret = async_data_read_start(exch, tmp_name, max_length);
    159                         if (ret == EOK) {
    160                                 names[i] = str_dup(tmp_name);
    161                                 ret = names[i] ? EOK : ENOMEM;
    162                         }
    163                         if (ret != EOK)
    164                                 break;
    165                 }
    166                 free(tmp_name);
     152                if (!names || !sizes)
     153                        ret = ENOMEM;
     154
     155                if (ret == EOK)
     156                        ret = async_data_read_start(exch, sizes,
     157                            name_count * sizeof(size_t));
     158                for (unsigned i = 0; i < name_count && ret == EOK; ++i) {
     159                        char *name = malloc(sizes[i] + 1);
     160                        if (name) {
     161                                bzero(name, sizes[i]);
     162                                ret = async_data_read_start(exch, name, sizes[i]);
     163                                names[i] = name;
     164                        } else {
     165                                ret = ENOMEM;
     166                        }
     167                }
     168                free(sizes);
    167169        }
    168170        async_exchange_end(exch);
     
    188190        if (!exch)
    189191                return ENOMEM;
    190         int ret = async_req_0_0(exch, IPC_M_HOUND_CONNECT);
     192        ipc_call_t call;
     193        aid_t id = async_send_0(exch, IPC_M_HOUND_CONNECT, &call);
     194        int ret = id ? EOK : EPARTY;
    191195        if (ret == EOK)
    192196                ret = async_data_write_start(exch, source, str_size(source));
    193197        if (ret == EOK)
    194198                ret = async_data_write_start(exch, sink, str_size(sink));
     199        async_wait_for(id, (sysarg_t*)&ret);
    195200        async_exchange_end(exch);
    196201        return ret;
     
    204209        if (!exch)
    205210                return ENOMEM;
    206         int ret = async_req_0_0(exch, IPC_M_HOUND_DISCONNECT);
     211        ipc_call_t call;
     212        aid_t id = async_send_0(exch, IPC_M_HOUND_DISCONNECT, &call);
     213        int ret = id ? EOK : EPARTY;
    207214        if (ret == EOK)
    208215                ret = async_data_write_start(exch, source, str_size(source));
    209216        if (ret == EOK)
    210217                ret = async_data_write_start(exch, sink, str_size(sink));
     218        async_wait_for(id, (sysarg_t*)&ret);
    211219        async_exchange_end(exch);
    212220        return ENOTSUP;
     
    304312                            server_iface->rem_context(server_iface->server, id);
    305313                        async_answer_0(callid, ret);
     314                        break;
     315                }
     316                case IPC_M_HOUND_GET_LIST: {
     317                        if (!server_iface || !server_iface->get_list) {
     318                                async_answer_0(callid, ENOTSUP);
     319                                break;
     320                        }
     321                        const char **list = NULL;
     322                        const int flags = IPC_GET_ARG1(call);
     323                        size_t count = IPC_GET_ARG2(call);
     324                        const bool conn = IPC_GET_ARG3(call);
     325                        char *conn_name = NULL;
     326                        int ret = EOK;
     327                        if (conn)
     328                                ret = async_data_write_accept(
     329                                    (void**)&conn_name, true, 0, 0, 0, 0);
     330
     331                        if (ret == EOK)
     332                                ret = server_iface->get_list(
     333                                    server_iface->server, &list, &count,
     334                                    conn_name, flags);
     335                        free(conn_name);
     336                        size_t *sizes = NULL;
     337                        if (count)
     338                                sizes = calloc(count, sizeof(size_t));
     339                        if (count && !sizes)
     340                                ret = ENOMEM;
     341                        async_answer_1(callid, ret, count);
     342
     343                        /* We are done */
     344                        if (count == 0 || ret != EOK)
     345                                break;
     346
     347                        /* Prepare sizes table */
     348                        for (unsigned i = 0; i < count; ++i)
     349                                sizes[i] = str_size(list[i]);
     350
     351                        /* Send sizes table */
     352                        ipc_callid_t id;
     353                        if (async_data_read_receive(&id, NULL)) {
     354                                ret = async_data_read_finalize(id, sizes,
     355                                    count * sizeof(size_t));
     356                        }
     357                        free(sizes);
     358
     359                        /* Proceed to send names */
     360                        for (unsigned i = 0; i < count; ++i) {
     361                                size_t size = str_size(list[i]);
     362                                ipc_callid_t id;
     363                                if (ret == EOK &&
     364                                    async_data_read_receive(&id, NULL)) {
     365                                        ret = async_data_read_finalize(id,
     366                                            list[i], size);
     367                                }
     368                                free(list[i]);
     369                        }
     370                        free(list);
     371                        break;
     372                }
     373                case IPC_M_HOUND_CONNECT: {
     374                        if (!server_iface || !server_iface->connect) {
     375                                async_answer_0(callid, ENOTSUP);
     376                                break;
     377                        }
     378                        void *source = NULL;
     379                        void *sink = NULL;
     380                        int ret =
     381                            async_data_write_accept(&source, true, 0, 0, 0, 0);
     382                        if (ret == EOK)
     383                                ret = async_data_write_accept(&sink,
     384                                    true, 0, 0, 0, 0);
     385                        if (ret == EOK)
     386                                ret = server_iface->connect(
     387                                    server_iface->server, source, sink);
     388                        free(source);
     389                        free(sink);
     390                        async_answer_0(callid, ret);
     391                        break;
     392                }
     393                case IPC_M_HOUND_DISCONNECT: {
     394                        if (!server_iface || !server_iface->disconnect) {
     395                                async_answer_0(callid, ENOTSUP);
     396                                break;
     397                        }
     398                        void *source = NULL;
     399                        void *sink = NULL;
     400                        int ret =
     401                            async_data_write_accept(&source, true, 0, 0, 0, 0);
     402                        if (ret == EOK)
     403                                ret = async_data_write_accept(&sink,
     404                                    true, 0, 0, 0, 0);
     405                        if (ret == EOK)
     406                                ret = server_iface->connect(
     407                                    server_iface->server, source, sink);
     408                        free(source);
     409                        free(sink);
     410                        async_answer_0(callid, ret);
     411                        break;
    306412                }
    307413                case IPC_M_HOUND_STREAM_ENTER: {
Note: See TracChangeset for help on using the changeset viewer.