GCOV Execution Analysis for plugin.c

The left column is the number of times the code was executed during the unit test suites.

Exec CodeLine #
 
Source:plugin.c
1
 
Graph:.libs/plugin.gcno
2
 
Data:.libs/plugin.gcda
3
 
Runs:378
4
 
Programs:378
5
 
/*      -*- linux-c -*-
6
 
 *
7
 
 * Copyright (c) 2003 by Intel Corp.
8
 
 * (C) Copyright IBM Corp. 2003-2004
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  This
13
 
 * file and program are licensed under a BSD style license.  See
14
 
 * the Copying file included with the OpenHPI distribution for
15
 
 * full licensing terms.
16
 
 *
17
 
 * Authors:
18
 
 *     Louis Zhuang < address removed >
19
 
 *     Sean Dague <http://dague.net/sean>
20
 
 *     David Judkovics < address removed >
21
 
 *     Renier Morales < address removed >
22
 
 */
23
 
24
 
#include <string.h>
25
 
#include <ltdl.h>
26
 
27
 
#include <glib.h>
28
 
#include <oh_plugin.h>
29
 
#include <oh_config.h>
30
 
#include <oh_error.h>
31
 
#include <oh_lock.h>
32
 
#include <config.h>
33
 
34
 
/*
35
 
 * List of plugins (oh_plugin).
36
 
 */
37
 
static GSList *plugin_list = NULL;
38
 
/*
39
 
 * Table of handlers (oh_handler).
40
 
 */
41
 
static GHashTable *handler_table = NULL;
42
 
/*
43
 
 * List of handler ids (unsigned int).
44
 
 */
45
 
static GSList *handler_ids = NULL;
46
 
47
 
48
 
extern GCond *oh_thread_wait;
49
 
50
 
void oh_cond_signal(void)
51
0 
{
52
0 
        g_cond_signal(oh_thread_wait);
53
 
}
54
 
55
 
/**
56
 
 * oh_init_ltdl
57
 
 *
58
 
 * Does all the initialization needed for the ltdl process to
59
 
 * work. It takes no arguments, and returns 0 on success, < 0 on error
60
 
 *
61
 
 * Returns: 0 on Success.
62
 
 **/
63
 
static int oh_init_ltdl(void)
64
374 
{
65
374 
        struct oh_global_param path_param = { .type = OPENHPI_PATH };
66
374 
        int err;
67
374 
        static int init_done = 0;
68
 
        
69
374 
        data_access_lock();
70
374 
        if (init_done) {
71
0 
                data_access_unlock();
72
0 
                return 0;
73
 
        }
74
 
75
374 
        err = lt_dlinit();
76
374 
        if (err != 0) {
77
0 
                dbg("Can not init ltdl");
78
0 
                data_access_unlock();
79
0 
                return -1;
80
 
        }
81
 
        
82
374 
        oh_get_global_param(&path_param);
83
 
84
374 
        err = lt_dlsetsearchpath(path_param.u.path);
85
374 
        if (err != 0) {
86
0 
                dbg("Can not set lt_dl search path");
87
0 
                oh_exit_ltdl();
88
0 
                data_access_unlock();
89
0 
                return -1;
90
 
        }
91
 
        
92
374 
        init_done = 1;
93
374 
        data_access_unlock();
94
 
95
374 
        return 0;
96
 
}
97
 
98
 
/**
99
 
 * oh_exit_ltdl
100
 
 *
101
 
 * Does everything needed to close the ltdl structures.
102
 
 *
103
 
 * Returns: 0 on Success.
104
 
 **/
105
 
int oh_exit_ltdl()
106
0 
{
107
0 
        int rv;
108
 
109
0 
        rv = lt_dlexit();
110
0 
        if (rv < 0) {
111
0 
                dbg("Could not exit ltdl!");
112
0 
                return -1;
113
 
        }
114
 
115
0 
        return 0;
116
 
}
117
 
118
 
/**
119
 
 * oh_lookup_plugin
120
 
 * @plugin_name
121
 
 *
122
 
 * Lookup and get a reference for @plugin_name.
123
 
 *
124
 
 * Returns: oh_plugin reference or NULL if plugin_name was not found.
125
 
 **/
126
 
struct oh_plugin *oh_lookup_plugin(char *plugin_name)
127
748 
{
128
748 
        GSList *node = NULL;
129
748 
        struct oh_plugin *plugin = NULL;
130
 
131
748 
        if (!plugin_name) {
132
0 
                dbg("ERROR getting plugin. Invalid parameter.");
133
0 
                return NULL;
134
 
        }
135
 
136
748 
        data_access_lock();
137
748 
        for (node = plugin_list; node != NULL; node = node->next) {
138
374 
                struct oh_plugin *p = node->data;
139
374 
                if(strcmp(p->name, plugin_name) == 0) {
140
374 
                        plugin = p;
141
374 
                        break;
142
 
                }
143
 
        }
144
748 
        data_access_unlock();
145
 
146
748 
        return plugin;
147
 
}
148
 
149
 
/**
150
 
 * oh_lookup_next_plugin
151
 
 * @plugin_name: IN. If NULL is passed, the first plugin in the list is returned.
152
 
 * @next_plugin_name: OUT. Buffer to print the next plugin name to.
153
 
 * @size: IN. Size of the buffer at @next_plugin_name.
154
 
 *
155
 
 * Returns: 0 on Success.
156
 
 **/
157
 
int oh_lookup_next_plugin(char *plugin_name,
158
 
                          char *next_plugin_name,
159
 
                          unsigned int size)
160
0 
{
161
0 
        GSList *node = NULL;
162
 
163
0 
        if (!next_plugin_name) {
164
0 
                dbg("ERROR. Invalid parameter.");
165
0 
                return -1;
166
 
        }
167
0 
        memset(next_plugin_name, '\0', size);
168
 
169
0 
        data_access_lock();
170
0 
        if (!plugin_name) {
171
0 
                if (plugin_list) {
172
0 
                        struct oh_plugin *plugin = plugin_list->data;
173
0 
                        strncpy(next_plugin_name, plugin->name, size);
174
0 
                        data_access_unlock();
175
0 
                        return 0;
176
 
                } else {
177
0 
                        trace("No plugins have been loaded yet.");
178
0 
                        data_access_unlock();
179
0 
                        return -1;
180
 
                }
181
 
        } else {
182
0 
                for (node = plugin_list; node != NULL; node = node->next) {
183
0 
                        struct oh_plugin *p = node->data;
184
0 
                        if (strcmp(p->name, plugin_name) == 0) {
185
0 
                                if (node->next) {
186
0 
                                        p = node->next->data;
187
0 
                                        strncpy(next_plugin_name, p->name, size);
188
0 
                                        data_access_unlock();
189
0 
                                        return 0;
190
 
                                } else
191
0 
                                        break;
192
 
                        }
193
 
                }
194
 
        }
195
0 
        data_access_unlock();
196
 
197
0 
        return -1;
198
 
}
199
 
200
 
/* list of static plugins. defined in plugin_static.c.in */
201
 
extern struct oh_static_plugin static_plugins[];
202
 
/**
203
 
 * oh_unload_plugin
204
 
 * @plugin_name
205
 
 *
206
 
 * Load plugin by name and make a instance.
207
 
 *
208
 
 * Returns: 0 on Success.
209
 
 **/
210
 
int oh_load_plugin(char *plugin_name)
211
374 
{
212
374 
        struct oh_plugin *plugin = NULL;
213
374 
        int (*get_interface) (struct oh_abi_v2 ** pp, const uuid_t uuid);
214
374 
        int err;
215
374 
        struct oh_static_plugin *p = static_plugins;
216
 
217
374 
        if (!plugin_name) {
218
0 
                dbg("ERROR. NULL plugin name passed.");
219
0 
                return -1;
220
 
        }
221
 
222
374 
        data_access_lock();
223
374 
        if (oh_init_ltdl()) {                
224
0 
                data_access_unlock();
225
0 
                dbg("ERROR. Could not initialize ltdl for loading plugins.");
226
0 
                return -1;
227
 
        }
228
 
        
229
374 
        if (oh_lookup_plugin(plugin_name)) {
230
0 
                dbg("Warning. Plugin %s already loaded. Not loading twice.",
231
 
                    plugin_name);
232
0 
                data_access_unlock();
233
0 
                return -1;
234
 
        }
235
 
236
374 
        plugin = (struct oh_plugin *)g_malloc0(sizeof(struct oh_plugin));
237
374 
        if (!plugin) {
238
0 
                dbg("Out of memory.");
239
0 
                data_access_unlock();
240
0 
                return -1;
241
 
        }
242
374 
        plugin->name = g_strdup(plugin_name);
243
374 
        plugin->refcount = 1;
244
 
        
245
 
        /* first take search plugin in the array of static plugin */
246
374 
        while( p->name ) {
247
0 
                if (!strcmp(plugin->name, p->name)) {
248
0 
                        plugin->dl_handle = 0;
249
0 
                        err = (*p->get_interface)((void **)&plugin->abi, UUID_OH_ABI_V2);
250
 
251
0 
                        if (err < 0 || !plugin->abi || !plugin->abi->open) {
252
0 
                                dbg("Can not get ABI V2");
253
0 
                                goto err1;
254
 
                        }
255
 
256
0 
                        trace( "found static plugin %s", p->name );
257
 
258
0 
                        plugin_list = g_slist_append(plugin_list, plugin);
259
0 
                        data_access_unlock();
260
 
261
0 
                        return 0;
262
 
                }
263
 
264
0 
                p++;
265
 
        }
266
 
267
374 
        plugin->dl_handle = lt_dlopenext(plugin->name);
268
374 
        if (plugin->dl_handle == NULL) {
269
0 
                dbg("Can not open %s plugin: %s", plugin->name, lt_dlerror());
270
0 
                goto err1;
271
 
        }
272
 
273
374 
        get_interface = lt_dlsym(plugin->dl_handle, "get_interface");
274
374 
        if (!get_interface) {
275
0 
                dbg("Can not get 'get_interface' symbol, is it a plugin?!");
276
0 
                goto err1;
277
 
        }
278
 
279
374 
        err = get_interface(&plugin->abi, UUID_OH_ABI_V2);
280
374 
        if (err < 0 || !plugin->abi || !plugin->abi->open) {
281
0 
                dbg("Can not get ABI V1");
282
0 
                goto err1;
283
 
        }
284
374 
        plugin_list = g_slist_append(plugin_list, plugin);
285
374 
        data_access_unlock();
286
 
287
374 
        return 0;
288
 
289
 
 err1:
290
0 
        if (plugin->dl_handle) {
291
0 
                lt_dlclose(plugin->dl_handle);
292
0 
                plugin->dl_handle = 0;
293
 
        }
294
0 
        data_access_unlock();
295
0 
        g_free(plugin);
296
 
297
0 
        return -1;
298
 
}
299
 
300
 
/**
301
 
 * oh_unload_plugin
302
 
 * @plugin_name
303
 
 *
304
 
 * Returns: 0 on Success.
305
 
 **/
306
 
int oh_unload_plugin(char *plugin_name)
307
0 
{
308
0 
        struct oh_plugin *plugin = NULL;
309
 
310
0 
        if (!plugin_name) {
311
0 
                dbg("ERROR unloading plugin. NULL parameter passed.");
312
0 
                return -1;
313
 
        }
314
 
        
315
0 
        data_access_lock();
316
 
317
0 
        plugin = oh_lookup_plugin(plugin_name);
318
0 
        if (!plugin) {
319
0 
                dbg("ERROR unloading plugin. Plugin not found.");
320
0 
                data_access_unlock();
321
0 
                return -2;
322
 
        }        
323
 
324
0 
        if (plugin->refcount > 1) {
325
0 
                dbg("ERROR unloading plugin. Handlers are still referencing it.");
326
0 
                data_access_unlock();
327
0 
                return -3;
328
 
        }
329
 
330
0 
        if (plugin->dl_handle) {
331
0 
                lt_dlclose(plugin->dl_handle);
332
0 
                plugin->dl_handle = 0;
333
 
        }
334
 
335
0 
        plugin_list = g_slist_remove(plugin_list, plugin);
336
0 
        data_access_unlock();
337
 
338
0 
        if (plugin->name)
339
0 
                g_free(plugin->name);
340
 
341
0 
        g_free(plugin);
342
 
343
0 
        return 0;
344
 
}
345
 
346
 
static int oh_init_handler_table(void)
347
374 
{
348
374 
        if (!handler_table)
349
374 
                handler_table = g_hash_table_new(g_int_hash, g_int_equal);
350
 
                
351
374 
        return (handler_table) ? 0 : -1;
352
 
}
353
 
354
 
/**
355
 
 * oh_lookup_handler
356
 
 * @hid
357
 
 *
358
 
 * Returns: NULL on Failure.
359
 
 **/
360
 
struct oh_handler *oh_lookup_handler(unsigned int hid)
361
1090 
{
362
1090 
        struct oh_handler *handler = NULL;
363
 
364
1090 
        data_access_lock();
365
1090 
        if (!handler_table) {
366
0 
                data_access_unlock();                
367
0 
                return NULL;
368
 
        }
369
 
        
370
1090 
        handler = g_hash_table_lookup(handler_table, &hid);
371
1090 
        data_access_unlock();
372
 
373
1090 
        return handler;
374
 
}
375
 
376
 
/**
377
 
 * oh_lookup_next_handler
378
 
 * @hid: If 0, will return the first handler id in the list.
379
 
 * @next_hid
380
 
 *
381
 
 * Returns: 0 on Success.
382
 
 **/
383
 
int oh_lookup_next_handler(unsigned int hid, unsigned int *next_hid)
384
1872 
{
385
1872 
        GSList *node = NULL;
386
 
387
1872 
        if (!next_hid) {
388
0 
                dbg("ERROR. Invalid parameter.");
389
0 
                return -1;
390
 
        }
391
1872 
        *next_hid = 0;
392
 
393
1872 
        data_access_lock();
394
1872 
        if (!hid) {
395
1123 
                if (handler_ids) {
396
1123 
                        unsigned int *id = handler_ids->data;
397
1123 
                        *next_hid = *id;
398
1123 
                        data_access_unlock();
399
1123 
                        return 0;
400
 
                } else {
401
0 
                        data_access_unlock();
402
0 
                        return -1;
403
 
                }
404
 
        } else {
405
749 
                for (node = handler_ids; node; node = node->next) {
406
749 
                        unsigned int *id = node->data;
407
749 
                        if (*id == hid) {
408
749 
                                if (node->next) {
409
0 
                                        id = node->next->data;
410
0 
                                        *next_hid = *id;
411
0 
                                        data_access_unlock();
412
0 
                                        return 0;
413
 
                                } else
414
0 
                                        break;
415
 
                        }
416
 
                }
417
 
        }
418
749 
        data_access_unlock();
419
 
420
749 
        return -1;
421
 
}
422
 
423
 
static struct oh_handler *new_handler(GHashTable *handler_config)
424
374 
{
425
374 
        struct oh_plugin *plugin = NULL;
426
374 
        struct oh_handler *handler = NULL;
427
374 
        static unsigned int handler_id = 1;
428
 
429
374 
        if (!handler_config) {
430
0 
                dbg("ERROR creating new handler. Invalid parameter.");
431
0 
                return NULL;
432
 
        }
433
 
434
374 
        handler = (struct oh_handler *)g_malloc0(sizeof(struct oh_handler));
435
374 
        if (!handler) {
436
0 
                dbg("Out of Memory!");
437
0 
                return NULL;
438
 
        }
439
 
440
374 
        plugin = oh_lookup_plugin((char *)g_hash_table_lookup(handler_config, "plugin"));
441
374 
        if(!plugin || plugin->refcount < 1) {
442
0 
                dbg("Attempt to create handler for unknown plugin %s",
443
 
                        (char *)g_hash_table_lookup(handler_config, "plugin"));
444
0 
                goto err;
445
 
        }
446
 
447
374 
        handler->plugin_name = g_strdup(plugin->name);
448
374 
        handler->abi = plugin->abi;
449
374 
        handler->config = handler_config;
450
 
        
451
374 
        handler->hnd = handler->abi->open(handler->config);
452
374 
        if (!handler->hnd) {
453
0 
                dbg("A plugin instance could not be opened.");
454
0 
                goto err;
455
 
        }
456
 
457
374 
        handler->id = handler_id++;
458
374 
        plugin->refcount++;
459
 
460
374 
        return handler;
461
 
err:
462
0 
        g_free(handler);
463
0 
        return NULL;
464
 
}
465
 
466
 
/**
467
 
 * oh_load_handler
468
 
 * @handler_config
469
 
 *
470
 
 * Returns: 0 on Failure, otherwise the handler id
471
 
 **/
472
 
unsigned int oh_load_handler (GHashTable *handler_config)
473
374 
{
474
374 
        struct oh_handler *handler;
475
 
476
374 
        if (!handler_config) {
477
0 
                dbg("ERROR loading handler. Invalid handler configuration passed.");
478
0 
                return 0;
479
 
        }
480
 
481
374 
        data_access_lock();
482
374 
        if (oh_init_handler_table()) {
483
0 
                data_access_unlock();
484
0 
                dbg("ERROR. Could not initialize handler table.");
485
0 
                return 0;
486
 
        }
487
 
488
374 
        handler = new_handler(handler_config);
489
 
490
374 
        if (handler == NULL) {
491
0 
                data_access_unlock();
492
0 
                return 0;
493
 
        }
494
 
495
374 
        g_hash_table_insert(handler_table,
496
 
                            &(handler->id),
497
 
                            handler);
498
374 
        handler_ids = g_slist_append(handler_ids, &(handler->id));
499
 
500
374 
        data_access_unlock();
501
 
502
374 
        return handler->id;
503
 
}
504
 
505
 
/**
506
 
 * oh_unload_handler
507
 
 * @hid
508
 
 *
509
 
 * Returns: 0 on Success.
510
 
 **/
511
 
int oh_unload_handler(unsigned int hid)
512
0 
{
513
0 
        struct oh_handler *handler = NULL;
514
0 
        struct oh_plugin *plugin = NULL;
515
 
516
0 
        if (!hid) {
517
0 
                dbg("ERROR unloading handler. Invalid handler id passed.");
518
0 
                return -1;
519
 
        }
520
 
521
0 
        data_access_lock();
522
0 
        handler = oh_lookup_handler(hid);
523
0 
        if (!handler) {
524
0 
                dbg("ERROR unloading handler. Handler not found.");
525
0 
                data_access_unlock();
526
0 
                return -1;
527
 
        }
528
 
        
529
0 
        if (handler->abi && handler->abi->close)
530
0 
                handler->abi->close(handler->hnd);
531
 
532
0 
        g_hash_table_remove(handler_table, &(handler->id));
533
0 
        handler_ids = g_slist_remove(handler_ids, &(handler->id));
534
0 
        plugin = oh_lookup_plugin(handler->plugin_name);
535
0 
        if (!plugin) {
536
0 
                dbg("WHAT?! Handler loaded, but plugin does not exist!");                
537
 
        } else {
538
0 
                plugin->refcount--;
539
 
        }
540
0 
        data_access_unlock();
541
 
        
542
0 
        g_free(handler->plugin_name);
543
0 
        g_free(handler);
544
 
545
0 
        return 0;
546
 
}
547