2 * \brief DOpE application manager module
4 * \author Norman Feske <nf2@inf.tu-dresden.de>
6 * This module is used to manage DOpE-clients.
7 * It handles all needed application specific
8 * information such as its name, variables etc.
12 * Copyright (C) 2002-2004 Norman Feske <nf2@os.inf.tu-dresden.de>
13 * Technische Universitaet Dresden, Operating Systems Research Group
15 * This file is part of the DOpE package, which is distributed under
16 * the terms of the GNU General Public Licence 2. Please see the
17 * COPYING file for details.
27 #define APP_NAMELEN 64 /* application identifier string length */
29 static struct hashtab_services *hashtab;
30 static struct thread_services *thread;
31 //static struct scope_services *scope;
34 char name[APP_NAMELEN]; /* identifier string of the application */
35 THREAD *app_thread; /* application thread */
36 SCOPE *rootscope; /* root scope of the application */
37 void *listener; /* associated result/event listener */
38 THREAD *list_thread; /* listener thread (optional) */
42 extern SCREEN *curr_scr;
44 static struct app *apps[MAX_APPS];
46 int init_appman(struct dope_services *d);
49 /**********************************
50 *** FUNCTIONS FOR INTERNAL USE ***
51 **********************************/
53 /*** RETURN THE FIRST FREE APPLICATION ID ***/
54 static s32 get_free_app_id(void) {
57 for (i=1; i<MAX_APPS; i++) {
58 if (!apps[i]) return i;
60 INFO(printf("AppMan(get_free_app_id): no free dope application id!\n");)
65 /*** CREATE NEW APPLICATION ***/
66 static struct app *new_app(void) {
69 /* get memory for application structure */
70 new = zalloc(sizeof(struct app));
72 INFO(printf("AppMan(new_app): out of memory!\n");)
76 /* create hash table to store the variables of the application */
77 // new->rootscope = (SCOPE *)scope->create();
79 new->app_thread = thread->alloc_thread();
84 /*** SET THE IDENTIFIER STRING OF AN APPLICATION ***/
85 static void set_app_name(struct app *app, const char *appname) {
88 if (!app || !appname) return;
90 /* copy application name into application data structure */
91 for (i=0;i<APP_NAMELEN;i++) {
92 app->name[i]=appname[i];
93 if (!appname[i]) break;
95 app->name[APP_NAMELEN-1]=0;
99 /*** TEST IF AN APP_ID IS A VALID ONE ***/
100 static u16 app_id_valid(u32 app_id) {
102 if (app_id>=MAX_APPS) {
103 INFO(printf("AppMan(app_id_value): invalid app_id (out of range)\n");)
107 INFO(printf("AppMan(unregister): invalid app_id (no application with this id)\n");)
114 /*** RETURN NAME OF APPLICATION WITH THE SPECIFIED ID ***/
115 static char *get_app_name(s32 app_id) {
117 if (!app_id_valid(app_id)) return "";
123 /*************************
124 *** SERVICE FUNCTIONS ***
125 *************************/
127 /*** REGISTER NEW APPLICATION ***
129 * app_name: identifier string for the application
130 * returns dope_client id
132 static s32 register_app(const char *app_name) {
135 newapp_id = get_free_app_id();
137 INFO(printf("AppMan(register): application registering failed (no free app id)\n");)
141 /* create data structures for the DOpE internal representation of the app */
142 apps[newapp_id] = new_app();
143 if (!apps[newapp_id]) {
144 INFO(printf("AppMan(register): application registering failed.\n");)
148 set_app_name(apps[newapp_id], app_name);
153 /*** UNREGISTER AN APPLICATION AND FREE ALL ASSOCIATED INTERNAL RESSOURCES ***/
154 static s32 unregister_app(u32 app_id) {
156 if (!app_id_valid(app_id)) return -1;
161 curr_scr->gen->lock((WIDGET *)curr_scr);
163 /* prevent any events to be delivered anymore */
164 app->listener = NULL;
166 /* delete root namespace */
167 if (app->rootscope) app->rootscope->gen->dec_ref((WIDGET *)app->rootscope);
169 /* deallocate thread ids */
170 if (app->list_thread) thread->free_thread(app->list_thread);
171 if (app->app_thread) thread->free_thread(app->app_thread);
173 /* free the memory for the internal application representation */
176 /* mark the corresponding app_id to be free */
179 curr_scr->gen->unlock((WIDGET *)curr_scr);
184 /*** DEFINE ROOT SCOPE OF AN APPLICATION ***/
185 static void set_rootscope(u32 app_id, SCOPE *rootscope) {
186 if (!app_id_valid(app_id) || !rootscope) return;
187 apps[app_id]->rootscope = rootscope;
188 if (curr_scr) curr_scr->gen->inc_ref((WIDGET *)curr_scr);
189 rootscope->scope->set_var(rootscope, "Screen", "screen", 255, (WIDGET *)curr_scr);
193 /*** REQUEST ROOT SCOPE OF AN APPLICATION ***/
194 static SCOPE *get_rootscope(u32 app_id) {
195 if (!app_id_valid(app_id)) return NULL;
196 return apps[app_id]->rootscope;
200 /*** REGISTER EVENT LISTENER DESTINATION POINT OF AN APPLICATION ***
202 * The listener is not necessarily a thread. It could be a socket descriptor
203 * or something else. We never know what hides behind the listener pointer.
205 static void reg_listener(s32 app_id, void *listener) {
206 if (!app_id_valid(app_id)) return;
207 apps[app_id]->listener = listener;
211 /*** REGISTER EVENT LISTENER THREAD OF AN APPLICATION ***
213 * We only store this optional listener thread id for proper resource deallocation.
215 static void reg_list_thread(s32 app_id, THREAD *listener_thread) {
216 if (!app_id_valid(app_id)) return;
217 apps[app_id]->list_thread = listener_thread;
221 /*** REQUEST EVENT LISTENER THREAD OF AN APPLICATION ***/
222 static void *get_listener(s32 app_id) {
223 if (!app_id_valid(app_id)) return NULL;
224 return apps[app_id]->listener;
228 /*** REGISTER APPLICATION THREAD ***/
229 static void reg_app_thread(s32 app_id, THREAD *app_thread) {
230 if (!app_id_valid(app_id)) return;
231 thread->copy_thread(app_thread, apps[app_id]->app_thread);
235 /*** REQUEST APPLICATION THREAD ***/
236 static THREAD *get_app_thread(s32 app_id) {
237 if (!app_id_valid(app_id)) return NULL;
238 return apps[app_id]->app_thread;
242 /*** FIND APPLICATION IF OF SPECIFIED APPLICATION THREAD ***/
243 static s32 app_id_of_thread(THREAD *app_thread) {
245 for (i=1; i<MAX_APPS; i++) {
246 if (apps[i] && thread->thread_equal(apps[i]->listener, app_thread)) {
247 INFO(printf("Appman(app_id_of_thread): found app_id, return %d\n", (int)i));
255 /*** RESOLVE APPLICATION ID BY ITS NAME ***/
256 static s32 app_id_of_name(char *app_name) {
258 for (i=1; i<MAX_APPS; i++) {
259 if (apps[i] && dope_streq(app_name, apps[i]->name, 255)) {
268 /*** LOCK APPLICATION FOR MUTUAL EXCLUSIVE MODIFICATIONS ***/
269 static void lock(s32 app_id) {
272 // if (!app_id_valid(app_id) || !apps[app_id]->rootscope) return;
273 // s = apps[app_id]->rootscope;
274 // s->gen->lock((WIDGET *)s);
275 //// thread->mutex_down(global_lock);
277 curr_scr->gen->lock((WIDGET *)curr_scr);
279 printf("AppMan(lock): lock not possible because curr_scr is not defined.\n");
284 /*** UNLOCK APPLICATION ***/
285 static void unlock(s32 app_id) {
288 // if (!app_id_valid(app_id) || !apps[app_id]->rootscope) return;
289 // s = apps[app_id]->rootscope;
290 // s->gen->unlock((WIDGET *)s);
291 //// thread->mutex_up(global_lock);
292 if (curr_scr) curr_scr->gen->unlock((WIDGET *)curr_scr);
296 /****************************************
297 *** SERVICE STRUCTURE OF THIS MODULE ***
298 ****************************************/
300 static struct appman_services services = {
318 /**************************
319 *** MODULE ENTRY POINT ***
320 **************************/
322 int init_appman(struct dope_services *d) {
324 hashtab = d->get_module("HashTable 1.0");
325 thread = d->get_module("Thread 1.0");
326 // scope = d->get_module("Scope 1.0");
328 // global_lock = thread->create_mutex(0);
330 d->register_module("ApplicationManager 1.0", &services);