source: mainline/uspace/lib/graph/graph.c@ 7afd12e5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7afd12e5 was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 14.2 KB
RevLine 
[6d5e378]1/*
2 * Copyright (c) 2011 Petr Koupy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup graph
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <assert.h>
37#include <errno.h>
38#include <inttypes.h>
39#include <stdio.h>
40#include <as.h>
[38d150e]41#include <stdlib.h>
[6d5e378]42#include "graph.h"
43
44#define NAMESPACE "graphemu"
45#define VISUALIZER_NAME "vsl"
46#define RENDERER_NAME "rnd"
47
48static sysarg_t namespace_idx = 0;
49static sysarg_t visualizer_idx = 0;
50static sysarg_t renderer_idx = 0;
51
52static LIST_INITIALIZE(visualizer_list);
53static LIST_INITIALIZE(renderer_list);
54
55static FIBRIL_MUTEX_INITIALIZE(visualizer_list_mtx);
56static FIBRIL_MUTEX_INITIALIZE(renderer_list_mtx);
57
58visualizer_t *graph_alloc_visualizer(void)
59{
[df2e621c]60 return ((visualizer_t *) malloc(sizeof(visualizer_t)));
[6d5e378]61}
62
63renderer_t *graph_alloc_renderer(void)
64{
65 // TODO
[df2e621c]66 return ((renderer_t *) malloc(sizeof(renderer_t)));
[6d5e378]67}
68
69void graph_init_visualizer(visualizer_t *vs)
70{
71 link_initialize(&vs->link);
72 atomic_set(&vs->ref_cnt, 0);
73 vs->notif_sess = NULL;
74 fibril_mutex_initialize(&vs->mode_mtx);
75 list_initialize(&vs->modes);
76 vs->mode_set = false;
77 vs->cells.data = NULL;
78 vs->dev_ctx = NULL;
79}
80
81void graph_init_renderer(renderer_t *rnd)
82{
83 // TODO
84 link_initialize(&rnd->link);
85 atomic_set(&rnd->ref_cnt, 0);
86}
87
[b7fd2a0]88errno_t graph_register_visualizer(visualizer_t *vs)
[6d5e378]89{
90 char node[LOC_NAME_MAXLEN + 1];
91 snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
92 namespace_idx, VISUALIZER_NAME, visualizer_idx++);
[a35b458]93
[6d5e378]94 category_id_t cat;
[b7fd2a0]95 errno_t rc = loc_category_get_id("visualizer", &cat, 0);
[df2e621c]96 if (rc != EOK)
[6d5e378]97 return rc;
[a35b458]98
[6d5e378]99 rc = loc_service_register(node, &vs->reg_svc_handle);
[df2e621c]100 if (rc != EOK)
[6d5e378]101 return rc;
[a35b458]102
[6d5e378]103 rc = loc_service_add_to_cat(vs->reg_svc_handle, cat);
104 if (rc != EOK) {
105 loc_service_unregister(vs->reg_svc_handle);
106 return rc;
107 }
[a35b458]108
[6d5e378]109 fibril_mutex_lock(&visualizer_list_mtx);
110 list_append(&vs->link, &visualizer_list);
111 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]112
[6d5e378]113 return rc;
114}
115
[b7fd2a0]116errno_t graph_register_renderer(renderer_t *rnd)
[6d5e378]117{
118 char node[LOC_NAME_MAXLEN + 1];
119 snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
120 namespace_idx, RENDERER_NAME, renderer_idx++);
[a35b458]121
[6d5e378]122 category_id_t cat;
[b7fd2a0]123 errno_t rc = loc_category_get_id("renderer", &cat, 0);
[df2e621c]124 if (rc != EOK)
[6d5e378]125 return rc;
[a35b458]126
[6d5e378]127 rc = loc_service_register(node, &rnd->reg_svc_handle);
[df2e621c]128 if (rc != EOK)
[6d5e378]129 return rc;
[a35b458]130
[6d5e378]131 rc = loc_service_add_to_cat(rnd->reg_svc_handle, cat);
132 if (rc != EOK) {
133 loc_service_unregister(rnd->reg_svc_handle);
134 return rc;
135 }
[a35b458]136
[6d5e378]137 fibril_mutex_lock(&renderer_list_mtx);
138 list_append(&rnd->link, &renderer_list);
139 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]140
[6d5e378]141 return rc;
142}
143
144visualizer_t *graph_get_visualizer(sysarg_t handle)
145{
146 visualizer_t *vs = NULL;
[a35b458]147
[6d5e378]148 fibril_mutex_lock(&visualizer_list_mtx);
[a35b458]149
[feeac0d]150 list_foreach(visualizer_list, link, visualizer_t, vcur) {
151 if (vcur->reg_svc_handle == handle) {
152 vs = vcur;
[6d5e378]153 break;
154 }
155 }
[a35b458]156
[6d5e378]157 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]158
[6d5e378]159 return vs;
160}
161
162renderer_t *graph_get_renderer(sysarg_t handle)
163{
164 renderer_t *rnd = NULL;
[a35b458]165
[6d5e378]166 fibril_mutex_lock(&renderer_list_mtx);
[a35b458]167
[feeac0d]168 list_foreach(renderer_list, link, renderer_t, rcur) {
169 if (rcur->reg_svc_handle == handle) {
170 rnd = rcur;
[6d5e378]171 break;
172 }
173 }
[a35b458]174
[6d5e378]175 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]176
[6d5e378]177 return rnd;
178}
179
[b7fd2a0]180errno_t graph_unregister_visualizer(visualizer_t *vs)
[6d5e378]181{
182 fibril_mutex_lock(&visualizer_list_mtx);
[b7fd2a0]183 errno_t rc = loc_service_unregister(vs->reg_svc_handle);
[6d5e378]184 list_remove(&vs->link);
185 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]186
[6d5e378]187 return rc;
188}
189
[b7fd2a0]190errno_t graph_unregister_renderer(renderer_t *rnd)
[6d5e378]191{
192 fibril_mutex_lock(&renderer_list_mtx);
[b7fd2a0]193 errno_t rc = loc_service_unregister(rnd->reg_svc_handle);
[6d5e378]194 list_remove(&rnd->link);
195 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]196
[6d5e378]197 return rc;
198}
199
200void graph_destroy_visualizer(visualizer_t *vs)
201{
202 assert(atomic_get(&vs->ref_cnt) == 0);
203 assert(vs->notif_sess == NULL);
204 assert(!fibril_mutex_is_locked(&vs->mode_mtx));
205 assert(list_empty(&vs->modes));
206 assert(vs->mode_set == false);
207 assert(vs->cells.data == NULL);
208 assert(vs->dev_ctx == NULL);
[a35b458]209
[6d5e378]210 free(vs);
211}
212
213void graph_destroy_renderer(renderer_t *rnd)
214{
215 // TODO
216 assert(atomic_get(&rnd->ref_cnt) == 0);
[a35b458]217
[6d5e378]218 free(rnd);
219}
220
[b7fd2a0]221errno_t graph_notify_mode_change(async_sess_t *sess, sysarg_t handle, sysarg_t mode_idx)
[6d5e378]222{
223 async_exch_t *exch = async_exchange_begin(sess);
[b7fd2a0]224 errno_t ret = async_req_2_0(exch, VISUALIZER_MODE_CHANGE, handle, mode_idx);
[6d5e378]225 async_exchange_end(exch);
[a35b458]226
[6d5e378]227 return ret;
228}
229
[b7fd2a0]230errno_t graph_notify_disconnect(async_sess_t *sess, sysarg_t handle)
[6d5e378]231{
232 async_exch_t *exch = async_exchange_begin(sess);
[b7fd2a0]233 errno_t ret = async_req_1_0(exch, VISUALIZER_DISCONNECT, handle);
[6d5e378]234 async_exchange_end(exch);
[a35b458]235
[6d5e378]236 async_hangup(sess);
[a35b458]237
[6d5e378]238 return ret;
239}
240
[984a9ba]241static void vs_claim(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]242{
243 vs->client_side_handle = IPC_GET_ARG1(*icall);
[b7fd2a0]244 errno_t rc = vs->ops.claim(vs);
[984a9ba]245 async_answer_0(icall, rc);
[6d5e378]246}
247
[984a9ba]248static void vs_yield(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]249{
250 /* Deallocate resources for the current mode. */
251 if (vs->mode_set) {
252 if (vs->cells.data != NULL) {
253 as_area_destroy((void *) vs->cells.data);
254 vs->cells.data = NULL;
255 }
256 }
[a35b458]257
[6d5e378]258 /* Driver might also deallocate resources for the current mode. */
[b7fd2a0]259 errno_t rc = vs->ops.yield(vs);
[a35b458]260
[7c3fb9b]261 /*
262 * Now that the driver was given a chance to deallocate resources,
263 * current mode can be unset.
264 */
[df2e621c]265 if (vs->mode_set)
[6d5e378]266 vs->mode_set = false;
[a35b458]267
[984a9ba]268 async_answer_0(icall, rc);
[6d5e378]269}
270
[984a9ba]271static void vs_enumerate_modes(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]272{
[df2e621c]273 size_t len;
[a35b458]274
[984a9ba]275 ipc_call_t call;
276 if (!async_data_read_receive(&call, &len)) {
277 async_answer_0(&call, EREFUSED);
278 async_answer_0(icall, EREFUSED);
[df2e621c]279 return;
280 }
[a35b458]281
[6d5e378]282 fibril_mutex_lock(&vs->mode_mtx);
283 link_t *link = list_nth(&vs->modes, IPC_GET_ARG1(*icall));
[a35b458]284
[6d5e378]285 if (link != NULL) {
286 vslmode_list_element_t *mode_elem =
287 list_get_instance(link, vslmode_list_element_t, link);
[a35b458]288
[984a9ba]289 errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
290 async_answer_0(icall, rc);
[6d5e378]291 } else {
[984a9ba]292 async_answer_0(&call, ENOENT);
293 async_answer_0(icall, ENOENT);
[6d5e378]294 }
[a35b458]295
[df2e621c]296 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]297}
298
[984a9ba]299static void vs_get_default_mode(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]300{
[984a9ba]301 ipc_call_t call;
[df2e621c]302 size_t len;
[984a9ba]303 if (!async_data_read_receive(&call, &len)) {
304 async_answer_0(&call, EREFUSED);
305 async_answer_0(icall, EREFUSED);
[df2e621c]306 return;
307 }
[a35b458]308
[6d5e378]309 fibril_mutex_lock(&vs->mode_mtx);
310 vslmode_list_element_t *mode_elem = NULL;
[a35b458]311
[feeac0d]312 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]313 if (cur->mode.index == vs->def_mode_idx) {
314 mode_elem = cur;
315 break;
316 }
317 }
[a35b458]318
[6d5e378]319 if (mode_elem != NULL) {
[984a9ba]320 errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
321 async_answer_0(icall, rc);
[6d5e378]322 } else {
323 fibril_mutex_unlock(&vs->mode_mtx);
[984a9ba]324 async_answer_0(&call, ENOENT);
325 async_answer_0(icall, ENOENT);
[6d5e378]326 }
[a35b458]327
[df2e621c]328 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]329}
330
[984a9ba]331static void vs_get_current_mode(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]332{
[984a9ba]333 ipc_call_t call;
[df2e621c]334 size_t len;
[984a9ba]335 if (!async_data_read_receive(&call, &len)) {
336 async_answer_0(&call, EREFUSED);
337 async_answer_0(icall, EREFUSED);
[df2e621c]338 return;
339 }
[a35b458]340
[6d5e378]341 if (vs->mode_set) {
[984a9ba]342 errno_t rc = async_data_read_finalize(&call, &vs->cur_mode, len);
343 async_answer_0(icall, rc);
[6d5e378]344 } else {
[984a9ba]345 async_answer_0(&call, ENOENT);
346 async_answer_0(icall, ENOENT);
[6d5e378]347 }
348}
349
[984a9ba]350static void vs_get_mode(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]351{
[984a9ba]352 ipc_call_t call;
[df2e621c]353 size_t len;
[984a9ba]354 if (!async_data_read_receive(&call, &len)) {
355 async_answer_0(&call, EREFUSED);
356 async_answer_0(icall, EREFUSED);
[df2e621c]357 return;
358 }
[a35b458]359
[6d5e378]360 sysarg_t mode_idx = IPC_GET_ARG1(*icall);
[a35b458]361
[6d5e378]362 fibril_mutex_lock(&vs->mode_mtx);
363 vslmode_list_element_t *mode_elem = NULL;
[a35b458]364
[feeac0d]365 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]366 if (cur->mode.index == mode_idx) {
367 mode_elem = cur;
368 break;
369 }
370 }
[a35b458]371
[6d5e378]372 if (mode_elem != NULL) {
[984a9ba]373 errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
374 async_answer_0(icall, rc);
[6d5e378]375 } else {
[984a9ba]376 async_answer_0(&call, ENOENT);
377 async_answer_0(icall, ENOENT);
[6d5e378]378 }
[a35b458]379
[df2e621c]380 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]381}
382
[984a9ba]383static void vs_set_mode(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]384{
[984a9ba]385 ipc_call_t call;
[df2e621c]386 size_t size;
387 unsigned int flags;
[a35b458]388
[df2e621c]389 /* Retrieve the shared cell storage for the new mode. */
[984a9ba]390 if (!async_share_out_receive(&call, &size, &flags)) {
391 async_answer_0(&call, EREFUSED);
392 async_answer_0(icall, EREFUSED);
[df2e621c]393 return;
394 }
[a35b458]395
[6d5e378]396 /* Retrieve mode index and version. */
397 sysarg_t mode_idx = IPC_GET_ARG1(*icall);
398 sysarg_t mode_version = IPC_GET_ARG2(*icall);
[a35b458]399
[6d5e378]400 /* Find mode in the list. */
401 fibril_mutex_lock(&vs->mode_mtx);
402 vslmode_list_element_t *mode_elem = NULL;
[a35b458]403
[feeac0d]404 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]405 if (cur->mode.index == mode_idx) {
406 mode_elem = cur;
407 break;
408 }
409 }
[a35b458]410
[df2e621c]411 if (mode_elem == NULL) {
[6d5e378]412 fibril_mutex_unlock(&vs->mode_mtx);
[984a9ba]413 async_answer_0(&call, ENOENT);
414 async_answer_0(icall, ENOENT);
[6d5e378]415 return;
416 }
[a35b458]417
[df2e621c]418 /* Extract mode description from the list node. */
419 vslmode_t new_mode = mode_elem->mode;
420 fibril_mutex_unlock(&vs->mode_mtx);
[a35b458]421
[6d5e378]422 /* Check whether the mode is still up-to-date. */
423 if (new_mode.version != mode_version) {
[984a9ba]424 async_answer_0(&call, EINVAL);
425 async_answer_0(icall, EINVAL);
[6d5e378]426 return;
427 }
[a35b458]428
[6d5e378]429 void *new_cell_storage;
[984a9ba]430 errno_t rc = async_share_out_finalize(&call, &new_cell_storage);
[6d5e378]431 if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
[984a9ba]432 async_answer_0(icall, ENOMEM);
[6d5e378]433 return;
434 }
[a35b458]435
[6d5e378]436 /* Change device internal state. */
437 rc = vs->ops.change_mode(vs, new_mode);
[a35b458]438
[6d5e378]439 /* Device driver could not establish new mode. Rollback. */
440 if (rc != EOK) {
441 as_area_destroy(new_cell_storage);
[984a9ba]442 async_answer_0(icall, ENOMEM);
[6d5e378]443 return;
444 }
[a35b458]445
[df2e621c]446 /*
447 * Because resources for the new mode were successfully
448 * claimed, it is finally possible to free resources
449 * allocated for the old mode.
450 */
[6d5e378]451 if (vs->mode_set) {
452 if (vs->cells.data != NULL) {
453 as_area_destroy((void *) vs->cells.data);
454 vs->cells.data = NULL;
455 }
456 }
[a35b458]457
[6d5e378]458 /* Insert new mode into the visualizer. */
459 vs->cells.width = new_mode.screen_width;
460 vs->cells.height = new_mode.screen_height;
461 vs->cells.data = (pixel_t *) new_cell_storage;
462 vs->cur_mode = new_mode;
463 vs->mode_set = true;
[a35b458]464
[984a9ba]465 async_answer_0(icall, EOK);
[6d5e378]466}
467
[984a9ba]468static void vs_update_damaged_region(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]469{
470 sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 16);
471 sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0x0000ffff);
[a35b458]472
[b7fd2a0]473 errno_t rc = vs->ops.handle_damage(vs,
[6d5e378]474 IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
475 IPC_GET_ARG3(*icall), IPC_GET_ARG4(*icall),
[df2e621c]476 x_offset, y_offset);
[984a9ba]477 async_answer_0(icall, rc);
[6d5e378]478}
479
[984a9ba]480static void vs_suspend(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]481{
[b7fd2a0]482 errno_t rc = vs->ops.suspend(vs);
[984a9ba]483 async_answer_0(icall, rc);
[6d5e378]484}
485
[984a9ba]486static void vs_wakeup(visualizer_t *vs, ipc_call_t *icall)
[6d5e378]487{
[b7fd2a0]488 errno_t rc = vs->ops.wakeup(vs);
[984a9ba]489 async_answer_0(icall, rc);
[6d5e378]490}
491
[984a9ba]492void graph_visualizer_connection(visualizer_t *vs, ipc_call_t *icall, void *arg)
[6d5e378]493{
494 /* Claim the visualizer. */
495 if (!cas(&vs->ref_cnt, 0, 1)) {
[984a9ba]496 async_answer_0(icall, ELIMIT);
[6d5e378]497 return;
498 }
[a35b458]499
[6d5e378]500 /* Accept the connection. */
[984a9ba]501 async_answer_0(icall, EOK);
[a35b458]502
[6d5e378]503 /* Establish callback session. */
[984a9ba]504 ipc_call_t call;
505 async_get_call(&call);
[6d5e378]506 vs->notif_sess = async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
[df2e621c]507 if (vs->notif_sess != NULL)
[984a9ba]508 async_answer_0(&call, EOK);
[df2e621c]509 else
[984a9ba]510 async_answer_0(&call, ELIMIT);
[a35b458]511
[6d5e378]512 /* Enter command loop. */
513 while (true) {
[984a9ba]514 async_get_call(&call);
[a35b458]515
[6d5e378]516 if (!IPC_GET_IMETHOD(call)) {
[984a9ba]517 async_answer_0(&call, EINVAL);
[6d5e378]518 break;
519 }
[a35b458]520
[6d5e378]521 switch (IPC_GET_IMETHOD(call)) {
522 case VISUALIZER_CLAIM:
[984a9ba]523 vs_claim(vs, &call);
[6d5e378]524 break;
525 case VISUALIZER_YIELD:
[984a9ba]526 vs_yield(vs, &call);
[6d5e378]527 goto terminate;
528 case VISUALIZER_ENUMERATE_MODES:
[984a9ba]529 vs_enumerate_modes(vs, &call);
[6d5e378]530 break;
531 case VISUALIZER_GET_DEFAULT_MODE:
[984a9ba]532 vs_get_default_mode(vs, &call);
[6d5e378]533 break;
534 case VISUALIZER_GET_CURRENT_MODE:
[984a9ba]535 vs_get_current_mode(vs, &call);
[6d5e378]536 break;
537 case VISUALIZER_GET_MODE:
[984a9ba]538 vs_get_mode(vs, &call);
[6d5e378]539 break;
540 case VISUALIZER_SET_MODE:
[984a9ba]541 vs_set_mode(vs, &call);
[6d5e378]542 break;
543 case VISUALIZER_UPDATE_DAMAGED_REGION:
[984a9ba]544 vs_update_damaged_region(vs, &call);
[6d5e378]545 break;
546 case VISUALIZER_SUSPEND:
[984a9ba]547 vs_suspend(vs, &call);
[6d5e378]548 break;
549 case VISUALIZER_WAKE_UP:
[984a9ba]550 vs_wakeup(vs, &call);
[6d5e378]551 break;
552 default:
[984a9ba]553 async_answer_0(&call, EINVAL);
[6d5e378]554 goto terminate;
555 }
556 }
[a35b458]557
[6d5e378]558terminate:
559 async_hangup(vs->notif_sess);
560 vs->notif_sess = NULL;
561 atomic_set(&vs->ref_cnt, 0);
562}
563
[984a9ba]564void graph_renderer_connection(renderer_t *rnd, ipc_call_t *icall, void *arg)
[6d5e378]565{
566 // TODO
[a35b458]567
[6d5e378]568 /* Accept the connection. */
569 atomic_inc(&rnd->ref_cnt);
[984a9ba]570 async_answer_0(icall, EOK);
[a35b458]571
[6d5e378]572 /* Enter command loop. */
573 while (true) {
[984a9ba]574 ipc_call_t call;
575 async_get_call(&call);
[a35b458]576
[6d5e378]577 if (!IPC_GET_IMETHOD(call)) {
[984a9ba]578 async_answer_0(&call, EINVAL);
[6d5e378]579 break;
580 }
[a35b458]581
[6d5e378]582 switch (IPC_GET_IMETHOD(call)) {
583 default:
[984a9ba]584 async_answer_0(&call, EINVAL);
[6d5e378]585 goto terminate;
586 }
587 }
[a35b458]588
[6d5e378]589terminate:
590 atomic_dec(&rnd->ref_cnt);
591}
592
[984a9ba]593void graph_client_connection(ipc_call_t *icall, void *arg)
[6d5e378]594{
595 /* Find the visualizer or renderer with the given service ID. */
[f9b2cb4c]596 visualizer_t *vs = graph_get_visualizer(IPC_GET_ARG2(*icall));
597 renderer_t *rnd = graph_get_renderer(IPC_GET_ARG2(*icall));
[a35b458]598
[df2e621c]599 if (vs != NULL)
[984a9ba]600 graph_visualizer_connection(vs, icall, arg);
[df2e621c]601 else if (rnd != NULL)
[984a9ba]602 graph_renderer_connection(rnd, icall, arg);
[df2e621c]603 else
[984a9ba]604 async_answer_0(icall, ENOENT);
[6d5e378]605}
606
607/** @}
608 */
Note: See TracBrowser for help on using the repository browser.