GCOV Execution Analysis for event.c

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

Exec CodeLine #
 
Source:event.c
1
 
Graph:.libs/event.gcno
2
 
Data:.libs/event.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
 
 *     David Judkovics < address removed >
20
 
 *     Sean Dague <http://dague.net/sean>
21
 
 *     Renier Morales < address removed >
22
 
 *     Racing Guo < address removed >
23
 
 */
24
 
25
 
#include <unistd.h>
26
 
#include <stdio.h>
27
 
#include <stdlib.h>
28
 
#include <string.h>
29
 
30
 
#include <openhpi.h>
31
 
#include <oh_event.h>
32
 
#include <glib.h>
33
 
34
 
#define OH_THREAD_SLEEP_TIME 2 * G_USEC_PER_SEC
35
 
36
 
static gboolean oh_is_threaded = FALSE;
37
 
GAsyncQueue *oh_process_q = NULL;
38
 
GCond *oh_thread_wait = NULL;
39
 
GThread *oh_event_thread = NULL;
40
 
GError *oh_event_thread_error = NULL;
41
 
GMutex *oh_thread_mutex = NULL;
42
 
43
 
gboolean oh_run_threaded()
44
5 
{
45
5 
        return oh_is_threaded;
46
 
}
47
 
48
 
static gpointer oh_event_thread_loop(gpointer data)
49
0 
{
50
0 
        GTimeVal time;
51
 
52
0 
        while(oh_run_threaded()) {
53
0 
                dbg("About to run through the event loop");
54
 
55
0 
                oh_get_events();
56
 
57
0 
                g_get_current_time(&time);
58
0 
                g_time_val_add(&time, OH_THREAD_SLEEP_TIME);
59
0 
                dbg("Going to sleep");
60
 
61
0 
                if (g_cond_timed_wait(oh_thread_wait, oh_thread_mutex, &time))
62
0 
                        dbg("SIGNALED: Got signal from plugin");
63
 
                else
64
0 
                        dbg("TIMEDOUT: Woke up, am looping again");
65
 
        }
66
0 
        g_thread_exit(0);
67
0 
        return 0;
68
 
}
69
 
70
 
/*
71
 
 *  The following is required to set up the thread state for
72
 
 *  the use of async queues.  This is true even if we aren't
73
 
 *  using live threads.
74
 
 */
75
 
int oh_event_init()
76
374 
{
77
374 
        struct oh_global_param threaded_param = { .type = OPENHPI_THREADED };
78
 
        
79
374 
        trace("Attempting to init event");
80
374 
        if (!g_thread_supported()) {
81
374 
                trace("Initializing thread support");
82
374 
                g_thread_init(NULL);
83
 
        } else {
84
0 
                trace("Already supporting threads");
85
 
        }
86
374 
        trace("Setting up event processing queue");
87
374 
        oh_process_q = g_async_queue_new();
88
 
        
89
374 
        oh_get_global_param(&threaded_param);
90
374 
        if (threaded_param.u.threaded) {
91
0 
                oh_is_threaded = TRUE;
92
0 
                oh_thread_wait = g_cond_new();
93
0 
                oh_thread_mutex = g_mutex_new();
94
0 
                oh_event_thread = g_thread_create(oh_event_thread_loop,
95
 
                                                  NULL, FALSE, &oh_event_thread_error);
96
 
        }
97
 
        
98
374 
        return 1;
99
 
}
100
 
101
 
int oh_event_final()
102
0 
{
103
0 
        g_async_queue_unref(oh_process_q);
104
0 
        if(oh_run_threaded()) {
105
0 
                g_mutex_free(oh_thread_mutex);
106
0 
                g_cond_free(oh_thread_wait);
107
 
        }
108
0 
        return 1;
109
 
}
110
 
111
 
/*
112
 
 *  Event processing is split up into 2 stages
113
 
 *
114
 
 *
115
 
 */
116
 
117
 
static SaErrorT harvest_events_for_handler(struct oh_handler *h)
118
380 
{
119
380 
        struct oh_event event;
120
380 
        struct oh_event *e2;
121
 
122
380 
        SaErrorT error = SA_OK;
123
 
124
4783 
        do {
125
4783 
                error = h->abi->get_event(h->hnd, &event);
126
4783 
                if(error < 1) {
127
380 
                        trace("Handler is out of Events");
128
 
                } else {
129
4403 
                        trace("Found event for handler %p", h);
130
4403 
                        e2 = oh_dup_oh_event(&event);
131
4403 
                        e2->hid = h->id;
132
4403 
                        g_async_queue_push(oh_process_q, e2);
133
 
                }
134
4783 
        } while(error > 0);
135
 
136
380 
        return error;
137
 
}
138
 
139
 
SaErrorT oh_harvest_events()
140
380 
{
141
380 
        SaErrorT error = SA_ERR_HPI_ERROR;
142
380 
        unsigned int hid = 0, next_hid;
143
380 
        struct oh_handler *h = NULL;
144
 
145
380 
        data_access_lock();
146
380 
        oh_lookup_next_handler(hid, &next_hid);
147
760 
        while (next_hid) {
148
380 
                hid = next_hid;
149
380 
                h = oh_lookup_handler(hid);
150
380 
                if (harvest_events_for_handler(h) == SA_OK && error)
151
0 
                        error = SA_OK;
152
 
153
380 
                oh_lookup_next_handler(hid, &next_hid);
154
 
        }
155
380 
        data_access_unlock();
156
 
157
380 
        return error;
158
 
}
159
 
160
 
static SaErrorT oh_add_event_to_del(SaHpiDomainIdT did, struct oh_hpi_event *e)
161
4403 
{
162
4403 
        struct oh_global_param logsev_param = { .type = OPENHPI_LOG_ON_SEV };
163
4403 
        struct oh_domain *d;
164
4403 
        SaErrorT rv = SA_OK;
165
 
        
166
4403 
        oh_get_global_param(&logsev_param);
167
 
168
4403 
        if (e->event.Severity <= logsev_param.u.log_on_sev) { /* less is more */
169
 
                /* yes, we need to add real domain support later here */
170
4403 
                d = oh_get_domain(did);
171
4403 
                if(d) {
172
4403 
                        rv = oh_el_append(d->del, &e->event, &e->rdr, &e->res);
173
4403 
                        oh_release_domain(d);
174
 
                } else {
175
0 
                        rv = SA_ERR_HPI_ERROR;
176
 
                }
177
 
        }
178
4403 
        return rv;
179
 
}
180
 
181
 
static int process_hpi_event(struct oh_event *full_event)
182
4403 
{
183
4403 
        int i;
184
4403 
        GArray *sessions = NULL;
185
4403 
        SaHpiSessionIdT sid;
186
4403 
        struct oh_domain *d = NULL;
187
4403 
        struct oh_hpi_event *e = NULL;
188
 
189
 
        /* We take the domain lock for the whole function here */
190
 
191
4403 
        d = oh_get_domain(full_event->did);
192
4403 
        if(!d) {
193
0 
                dbg("Domain %d doesn't exist", full_event->did);
194
0 
                return -1; /* FIXME: should this be -1? */
195
 
        }
196
 
197
4403 
        e = &(full_event->u.hpi_event);
198
 
199
4403 
        if (e->res.ResourceCapabilities & SAHPI_CAPABILITY_MANAGED_HOTSWAP
200
 
            && e->event.EventType == SAHPI_ET_HOTSWAP) {
201
10 
                hotswap_push_event(&hs_eq, full_event);
202
10 
                trace("Pushed hotswap event");
203
 
        }
204
 
205
 
        /* FIXME: Add event to DEL */
206
4403 
        trace("About to add to EL");
207
4403 
        oh_add_event_to_del(d->id, e);
208
4403 
        trace("Added event to EL");
209
 
210
 
        /*
211
 
         * TODO: Here is where we need the SESSION MULTIPLEXING code
212
 
         */
213
 
214
 
        /* FIXME: yes, we need to figure out the real domain at some point */
215
4403 
        trace("About to get session list");
216
4403 
        sessions = oh_list_sessions(oh_get_default_domain_id());
217
4403 
        trace("process_hpi_event, done oh_list_sessions");
218
 
219
 
        /* multiplex event to the appropriate sessions */
220
8806 
        for(i = 0; i < sessions->len; i++) {
221
4403 
                SaHpiBoolT is_subscribed = SAHPI_FALSE;
222
4403 
                sid = g_array_index(sessions, SaHpiSessionIdT, i);
223
 
224
4403 
                oh_get_session_subscription(sid, &is_subscribed);
225
4403 
                if(is_subscribed) {
226
0 
                        oh_queue_session_event(sid, full_event);
227
 
                }
228
 
        }
229
4403 
        g_array_free(sessions, TRUE);
230
4403 
        trace("process_hpi_event, done multiplex event => sessions");
231
 
232
4403 
        oh_release_domain(d);
233
4403 
        trace("process_hpi_event, done oh_release_domain");
234
 
235
4403 
        return 0;
236
 
}
237
 
238
 
static int process_resource_event(struct oh_event *e)
239
1099 
{
240
1099 
        int rv;
241
1099 
        RPTable *rpt = NULL;
242
1099 
        struct oh_domain *d = NULL;
243
1099 
        struct oh_event hpie;
244
 
245
1099 
        d = oh_get_domain(e->did);
246
1099 
        if(!d) {
247
0 
                dbg("Domain %d doesn't exist", e->did);
248
0 
                return -1;
249
 
        }
250
1099 
        rpt = &(d->rpt);
251
 
252
1099 
        memset(&hpie, 0, sizeof(hpie));
253
1099 
        if (e->type == OH_ET_RESOURCE_DEL) {
254
1 
                rv = oh_remove_resource(rpt,e->u.res_event.entry.ResourceId);
255
1 
                trace("Resource %d in Domain %d has been REMOVED.",
256
 
                      e->u.res_event.entry.ResourceId,
257
 
                      e->did);
258
 
259
1 
                hpie.did = e->did;
260
1 
                hpie.u.hpi_event.event.Severity = e->u.res_event.entry.ResourceSeverity;
261
1 
                hpie.u.hpi_event.event.Source = e->u.res_event.entry.ResourceId;
262
1 
                hpie.u.hpi_event.event.EventType = SAHPI_ET_RESOURCE;
263
1 
                hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType =
264
 
                        SAHPI_RESE_RESOURCE_FAILURE;
265
 
266
 
        } else {
267
1098 
                struct oh_resource_data *rd = g_malloc0(sizeof(struct oh_resource_data));
268
 
269
1098 
                if (!rd) {
270
0 
                        dbg("Couldn't allocate resource data");
271
0 
                        return SA_ERR_HPI_OUT_OF_MEMORY;
272
 
                }
273
 
274
1098 
                rd->hid = e->hid;
275
1098 
                rd->controlled = 0;
276
1098 
                rd->auto_extract_timeout = get_default_hotswap_auto_extract_timeout();
277
 
278
1098 
                rv = oh_add_resource(rpt,&(e->u.res_event.entry),rd,0);
279
1098 
                trace("Resource %d in Domain %d has been ADDED.",
280
 
                      e->u.res_event.entry.ResourceId,
281
 
                      e->did);
282
 
283
1098 
                hpie.did = e->did;
284
1098 
                hpie.u.hpi_event.event.Severity = e->u.res_event.entry.ResourceSeverity;
285
1098 
                hpie.u.hpi_event.event.Source = e->u.res_event.entry.ResourceId;
286
1098 
                hpie.u.hpi_event.event.EventType = SAHPI_ET_RESOURCE;
287
1098 
                hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType =
288
 
                        SAHPI_RESE_RESOURCE_ADDED;
289
 
        }
290
1099 
        oh_release_domain(d);
291
 
292
1099 
        if (rv == SA_OK) {
293
1099 
                rv = process_hpi_event(&hpie);
294
 
        }
295
 
296
1099 
        return rv;
297
 
}
298
 
299
 
static int process_rdr_event(struct oh_event *e)
300
2928 
{
301
2928 
        int rv;
302
2928 
        SaHpiResourceIdT rid = e->u.rdr_event.parent;
303
2928 
        RPTable *rpt = NULL;
304
2928 
        struct oh_domain *d = NULL;
305
2928 
        struct oh_event hpie;
306
 
307
 
308
2928 
        d = oh_get_domain(e->did);
309
 
310
 
        /* get the RPT for this domain */
311
2928 
        if(!d) {
312
0 
                dbg("Domain %d doesn't exist", e->did);
313
0 
                return -1;
314
 
        }
315
2928 
        rpt = &(d->rpt);
316
 
317
2928 
        if (e->type == OH_ET_RDR_DEL) {  /* DELETE event */
318
 
319
0 
                if (!(rv = oh_remove_rdr(rpt, rid, e->u.rdr_event.rdr.RecordId)) ) {
320
0 
                        dbg("SUCCESS: RDR %x in Resource %d in Domain %d has been REMOVED.",
321
 
                            e->u.rdr_event.rdr.RecordId, rid, e->did);
322
 
                } else {
323
0 
                        dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been REMOVED.",
324
 
                            e->u.rdr_event.rdr.RecordId, rid, e->did);
325
 
                }
326
 
327
 
                /* build event for event queue */
328
 
329
 
        } else { /* ADD event */
330
 
331
2928 
                if(!(rv = oh_add_rdr(rpt, rid, &(e->u.rdr_event.rdr), NULL, 0))) {
332
2928 
                        dbg("SUCCES: RDR %x in Resource %d in Domain %d has been ADDED.",
333
 
                            e->u.rdr_event.rdr.RecordId, rid, e->did);
334
 
                } else {
335
0 
                        dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been ADDED.",
336
 
                            e->u.rdr_event.rdr.RecordId, rid, e->did);
337
 
                }
338
 
339
 
                /* build event for event queue */
340
2928 
                hpie.did = e->did;
341
 
342
 
                //hpie.u.hpi_event.event.Severity = e->u.rdr_event.rdr.RdrType;
343
2928 
                hpie.u.hpi_event.event.Source = e->u.rdr_event.parent;
344
2928 
                hpie.u.hpi_event.event.EventType = e->u.rdr_event.rdr.RdrType;
345
2928 
                hpie.u.hpi_event.rdr = e->u.rdr_event.rdr;
346
 
//                hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType =
347
 
//                        SAHPI_RESE_RESOURCE_ADDED;
348
 
/*
349
 
                switch (e->u.rdr_event.rdr.RdrType) {
350
 
                case SAHPI_NO_RECORD:
351
 
                        dbg("SAHPI_NO_RECORD: process_rdr_event");
352
 
                        break;
353
 
                case SAHPI_CTRL_RDR:.
354
 
                        break;
355
 
                case SAHPI_SENSOR_RDR;
356
 
                        break;
357
 
                case SAHPI_INVENTORY_RDR;
358
 
                        hpie.u.hpi_event
359
 
                        break;
360
 
                case SAHPI_WATCHDOG_RDR;
361
 
                        break;
362
 
                case SAHPI_ANNUNCIATOR_RDR;
363
 
                        break;
364
 
                default:
365
 
                        dbg("ERROR: process_rdr_event, unknown SaHpiRdrTypeT Type");
366
 
                        break;
367
 
                }
368
 
*/
369
 
        }
370
 
371
2928 
        oh_release_domain(d);
372
 
373
2928 
        if (rv == SA_OK) {
374
2928 
                rv = process_hpi_event(&hpie);
375
2928 
                dbg("process_rdr_event,   done process_hpi_event");
376
 
        }
377
 
378
2928 
        return rv;
379
 
380
 
/*      need this after different type rdr events are processed above FIXME:DJ
381
 
        otherwise rdr events are never palced on eventq
382
 
        if(rv == SA_OK) {
383
 
                rv = process_hpi_event(&hpie);
384
 
        }
385
 
*/
386
 
}
387
 
388
 
SaErrorT oh_process_events()
389
4783 
{
390
4783 
        struct oh_event *e;
391
 
392
4783 
        while((e = g_async_queue_try_pop(oh_process_q)) != NULL) {
393
 
394
 
                /* FIXME: add real check if handler is allowed to push event
395
 
                   to the domain id in the event */
396
4403 
                if((e->did != oh_get_default_domain_id()) &&
397
 
		   (e->did != SAHPI_UNSPECIFIED_DOMAIN_ID)) {
398
0 
                        dbg("Domain Id %d not valid for event", e->did);
399
0 
                        g_free(e);
400
0 
                        continue;
401
 
                }
402
 
403
4403 
                switch(e->type) {
404
 
                case OH_ET_RESOURCE:
405
1098 
                        trace("Event Type = Resource");
406
1098 
                        process_resource_event(e);
407
1098 
                        break;
408
 
                case OH_ET_RESOURCE_DEL:
409
1 
                        trace("Event Type = Resource Delete");
410
1 
                        process_resource_event(e);
411
1 
                        break;
412
 
                case OH_ET_RDR:
413
2928 
                        trace("Event Type = RDR");
414
2928 
                        process_rdr_event(e);
415
2928 
                        break;
416
 
                case OH_ET_RDR_DEL:
417
0 
                        trace("Event Type = RDR Delete");
418
0 
                        process_rdr_event(e);
419
0 
                        break;
420
 
                case OH_ET_HPI:
421
376 
                        trace("Event Type = HPI Event");
422
376 
                        process_hpi_event(e);
423
376 
                        break;
424
 
                default:
425
0 
                        trace("Event Type = Unknown Event");
426
 
                }
427
 
        }
428
380 
        g_free(e);
429
380 
        return SA_OK;
430
 
}
431
 
432
 
SaErrorT oh_get_events()
433
380 
{
434
380 
        SaErrorT rv = SA_OK;
435
 
436
380 
        dbg("About to harvest events in the loop");
437
380 
        rv = oh_harvest_events();
438
380 
        if(rv != SA_OK) {
439
380 
                dbg("Error on harvest of events.");
440
 
        }
441
 
442
380 
        rv = oh_process_events();
443
380 
        if(rv != SA_OK) {
444
0 
                dbg("Error on processing of events, aborting");
445
 
        }
446
 
447
380 
        process_hotswap_policy();
448
 
449
380 
        return rv;
450
 
}
451