source: mainline/uspace/app/vlaunch/vlaunch.c@ 1c635d6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1c635d6 was 1c635d6, checked in by Martin Sucha <sucha14@…>, 11 years ago

Do not hold a task's return value after it has disconnected.

Holding the task's return value meant that if nobody waited
for task's result, it polluted NS's memory. This was apparently
done because of a race between spawning a task and waiting for it.

We solve this problem in another way: ns discards the return value
as soon as the task disconnects from it. This typically happens
when the task finishes its execution. In order to avoid the race,
we send the wait request to ns while spawning the task (i.e. when
we talk to the loader), but before we allow the loaded program
to run.

Fixes #132

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[6d5e378]1/*
2 * Copyright (c) 2012 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 vlaunch
30 * @{
31 */
32/** @file
33 */
34
[3e6a98c5]35#include <stdbool.h>
[6d5e378]36#include <errno.h>
37#include <stdio.h>
38#include <malloc.h>
39#include <io/pixel.h>
40#include <task.h>
41#include <str.h>
42#include <str_error.h>
[b5674b2]43#include <loc.h>
44#include <fibril_synch.h>
45#include <io/pixel.h>
46#include <device/led_dev.h>
[6d5e378]47
48#include <window.h>
49#include <grid.h>
50#include <button.h>
51#include <label.h>
[b8f1a349]52#include <canvas.h>
[6d5e378]53
[b8f1a349]54#include <surface.h>
55#include <source.h>
56#include <drawctx.h>
57#include <codec/tga.h>
58
59#include "images.h"
60
61#define NAME "vlaunch"
62
[b4f43a1]63#define LOGO_WIDTH 196
64#define LOGO_HEIGHT 66
[6d5e378]65
[b5674b2]66#define PERIOD 1000000
67#define COLORS 7
68
[6d5e378]69static char *winreg = NULL;
[b5674b2]70static fibril_timer_t *timer = NULL;
71static list_t led_devs;
72
73static pixel_t colors[COLORS] = {
74 PIXEL(0xff, 0xff, 0x00, 0x00),
75 PIXEL(0xff, 0x00, 0xff, 0x00),
76 PIXEL(0xff, 0x00, 0x00, 0xff),
77 PIXEL(0xff, 0xff, 0xff, 0x00),
78 PIXEL(0xff, 0xff, 0x00, 0xff),
79 PIXEL(0xff, 0x00, 0xff, 0xff),
80 PIXEL(0xff, 0xff, 0xff, 0xff)
81};
82
83static unsigned int color = 0;
84
85typedef struct {
86 link_t link;
87 service_id_t svc_id;
88 async_sess_t *sess;
89} led_dev_t;
[6d5e378]90
91static int app_launch(const char *app)
92{
93 printf("%s: Spawning %s %s \n", NAME, app, winreg);
[b5674b2]94
[6d5e378]95 task_id_t id;
[1c635d6]96 task_wait_t wait;
97 int rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
[6d5e378]98 if (rc != EOK) {
99 printf("%s: Error spawning %s %s (%s)\n", NAME, app,
100 winreg, str_error(rc));
101 return -1;
102 }
[b5674b2]103
104 task_exit_t texit;
105 int retval;
[1c635d6]106 rc = task_wait(&wait, &texit, &retval);
[b5674b2]107 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
[6d5e378]108 printf("%s: Error retrieving retval from %s (%s)\n", NAME,
109 app, str_error(rc));
110 return -1;
111 }
[b5674b2]112
[6d5e378]113 return retval;
114}
115
116static void on_vterm(widget_t *widget, void *data)
117{
118 app_launch("/app/vterm");
119}
120
121static void on_vdemo(widget_t *widget, void *data)
122{
123 app_launch("/app/vdemo");
124}
125
126static void on_vlaunch(widget_t *widget, void *data)
127{
128 app_launch("/app/vlaunch");
129}
130
[b5674b2]131static void timer_callback(void *data)
132{
133 pixel_t next_color = colors[color];
134
135 color++;
136 if (color >= COLORS)
137 color = 0;
138
139 list_foreach(led_devs, link, led_dev_t, dev) {
140 if (dev->sess)
141 led_dev_color_set(dev->sess, next_color);
142 }
143
144 fibril_timer_set(timer, PERIOD, timer_callback, NULL);
145}
146
147static void loc_callback(void)
148{
149 category_id_t led_cat;
150 int rc = loc_category_get_id("led", &led_cat, IPC_FLAG_BLOCKING);
151 if (rc != EOK)
152 return;
153
154 service_id_t *svcs;
155 size_t count;
156 rc = loc_category_get_svcs(led_cat, &svcs, &count);
157 if (rc != EOK)
158 return;
159
160 for (size_t i = 0; i < count; i++) {
161 bool known = false;
162
163 /* Determine whether we already know this device. */
164 list_foreach(led_devs, link, led_dev_t, dev) {
165 if (dev->svc_id == svcs[i]) {
166 known = true;
167 break;
168 }
169 }
170
171 if (!known) {
172 led_dev_t *dev = (led_dev_t *) calloc(1, sizeof(led_dev_t));
173 if (!dev)
174 continue;
175
176 link_initialize(&dev->link);
177 dev->svc_id = svcs[i];
178 dev->sess = loc_service_connect(EXCHANGE_SERIALIZE, svcs[i], 0);
179
180 list_append(&dev->link, &led_devs);
181 }
182 }
183
184 // FIXME: Handle LED device removal
185
186 free(svcs);
187}
188
[6d5e378]189int main(int argc, char *argv[])
190{
[87c0a45]191 if (argc < 2) {
[6d5e378]192 printf("Compositor server not specified.\n");
193 return 1;
194 }
[bdf3c0c]195
[b5674b2]196 list_initialize(&led_devs);
197 int rc = loc_register_cat_change_cb(loc_callback);
198 if (rc != EOK) {
199 printf("Unable to register callback for device discovery.\n");
200 return 1;
201 }
202
[78192cc7]203 timer = fibril_timer_create(NULL);
[b5674b2]204 if (!timer) {
205 printf("Unable to create timer.\n");
206 return 1;
207 }
208
[b8f1a349]209 surface_t *logo = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
210 if (!logo) {
211 printf("Unable to decode logo.\n");
212 return 1;
213 }
214
[bdf3c0c]215 winreg = argv[1];
[62fbb7e]216 window_t *main_window = window_open(argv[1], true, true, "vlaunch");
[bdf3c0c]217 if (!main_window) {
218 printf("Cannot open main window.\n");
219 return 1;
220 }
221
[9e7898e]222 pixel_t grd_bg = PIXEL(255, 255, 255, 255);
[296e124e]223
224 pixel_t btn_bg = PIXEL(255, 255, 255, 255);
225 pixel_t btn_fg = PIXEL(255, 186, 186, 186);
226 pixel_t btn_text = PIXEL(255, 0, 0, 0);
227
[9e7898e]228 pixel_t lbl_bg = PIXEL(255, 255, 255, 255);
[296e124e]229 pixel_t lbl_text = PIXEL(255, 0, 0, 0);
[bdf3c0c]230
[b8f1a349]231 canvas_t *logo_canvas = create_canvas(NULL, LOGO_WIDTH, LOGO_HEIGHT,
232 logo);
[bdf3c0c]233 label_t *lbl_caption = create_label(NULL, "Launch application:", 16,
[296e124e]234 lbl_bg, lbl_text);
[bdf3c0c]235 button_t *btn_vterm = create_button(NULL, "vterm", 16, btn_bg,
[296e124e]236 btn_fg, btn_text);
[bdf3c0c]237 button_t *btn_vdemo = create_button(NULL, "vdemo", 16, btn_bg,
[296e124e]238 btn_fg, btn_text);
[bdf3c0c]239 button_t *btn_vlaunch = create_button(NULL, "vlaunch", 16, btn_bg,
[296e124e]240 btn_fg, btn_text);
[395ca2e]241 grid_t *grid = create_grid(window_root(main_window), 1, 5, grd_bg);
[bdf3c0c]242
[b8f1a349]243 if ((!logo_canvas) || (!lbl_caption) || (!btn_vterm) ||
244 (!btn_vdemo) || (!btn_vlaunch) || (!grid)) {
[bdf3c0c]245 window_close(main_window);
246 printf("Cannot create widgets.\n");
247 return 1;
248 }
249
250 sig_connect(&btn_vterm->clicked, NULL, on_vterm);
251 sig_connect(&btn_vdemo->clicked, NULL, on_vdemo);
252 sig_connect(&btn_vlaunch->clicked, NULL, on_vlaunch);
253
[b8f1a349]254 grid->add(grid, &logo_canvas->widget, 0, 0, 1, 1);
[395ca2e]255 grid->add(grid, &lbl_caption->widget, 0, 1, 1, 1);
256 grid->add(grid, &btn_vterm->widget, 0, 2, 1, 1);
257 grid->add(grid, &btn_vdemo->widget, 0, 3, 1, 1);
258 grid->add(grid, &btn_vlaunch->widget, 0, 4, 1, 1);
[bdf3c0c]259
[62fbb7e]260 window_resize(main_window, 0, 0, 210, 130 + LOGO_HEIGHT,
261 WINDOW_PLACEMENT_RIGHT | WINDOW_PLACEMENT_TOP);
[bdf3c0c]262 window_exec(main_window);
[b8f1a349]263
[b5674b2]264 fibril_timer_set(timer, PERIOD, timer_callback, NULL);
265
[bdf3c0c]266 task_retval(0);
267 async_manager();
268
269 return 0;
[6d5e378]270}
271
272/** @}
273 */
Note: See TracBrowser for help on using the repository browser.