~ubuntu-branches/ubuntu/vivid/openipmi/vivid

« back to all changes in this revision

Viewing changes to lib/opq.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2006-09-15 17:56:24 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060915175624-ljk0mg3xtcm65tvm
Tags: 2.0.7-1
* new upstream release from 2006-06-08
  Thanks to John Wright <john.wright hp.com> for initial work
  (closes: Bug#380149)
* updated Standards Version
* new binaries openipmicmd, openipmish, rmcp_ping

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include <OpenIPMI/internal/ilist.h>
41
41
#include <OpenIPMI/internal/opq.h>
42
42
 
43
 
typedef struct opq_elem_s
 
43
struct opq_elem_s
44
44
{
45
45
    int               block;
46
46
    opq_handler_cb    handler;
48
48
    opq_done_cb       done;
49
49
    void              *done_data;
50
50
    struct opq_elem_s *next;
51
 
} opq_elem_t;
 
51
    ilist_item_t      ilist_item;
 
52
};
52
53
 
53
54
struct opq_s
54
55
{
59
60
    opq_done_cb    done_handler;
60
61
    void           *done_data;
61
62
    int            blocked;
 
63
    int            in_destroy;
62
64
};
63
65
 
64
66
static void
114
116
    opq_elem_t *elem = (opq_elem_t *) item;
115
117
 
116
118
    elem->handler(elem->handler_data, 1);
117
 
    ipmi_mem_free(elem);
 
119
    /* Memory for this is in elem, so we must delete it before we free
 
120
       the elem. */
 
121
    ilist_delete(iter);
 
122
    opq_free_elem(elem);
118
123
}
119
124
 
120
125
void
121
126
opq_destroy(opq_t *opq)
122
127
{
 
128
    /* Only allow this to be done once.  Callbacks might call this
 
129
       again. */
 
130
    opq_lock(opq);
 
131
    if (opq->in_destroy) {
 
132
        opq_unlock(opq);
 
133
        return;
 
134
    }
 
135
    opq->in_destroy = 1;
 
136
    opq_unlock(opq);
 
137
 
123
138
    ilist_iter(opq->ops, opq_destroy_item, NULL);
124
139
    free_ilist(opq->ops);
125
140
    if (opq->lock)
127
142
    ipmi_mem_free(opq);
128
143
}
129
144
 
 
145
static void
 
146
start_next_op(opq_t *opq)
 
147
{
 
148
    ilist_iter_t iter;
 
149
    opq_elem_t   *elem;
 
150
    int          success;
 
151
 
 
152
    ilist_init_iter(&iter, opq->ops);
 
153
    ilist_first(&iter);
 
154
    elem = ilist_get(&iter);
 
155
    while (elem) {
 
156
        ilist_delete(&iter);
 
157
        opq->done_handler = elem->done;
 
158
        opq->done_data = elem->done_data;
 
159
        opq_unlock(opq);
 
160
        success = elem->handler(elem->handler_data, 0);
 
161
        opq_free_elem(elem);
 
162
        opq_lock(opq);
 
163
        if (success == OPQ_HANDLER_STARTED)
 
164
            break;
 
165
        ilist_first(&iter);
 
166
        elem = ilist_get(&iter);
 
167
    }
 
168
    if (!elem)
 
169
        opq->in_handler = 0;
 
170
}
 
171
 
 
172
opq_elem_t *
 
173
opq_alloc_elem(void)
 
174
{
 
175
    opq_elem_t *elem;
 
176
    elem = ipmi_mem_alloc(sizeof(opq_elem_t));
 
177
    return elem;
 
178
}
 
179
 
 
180
void
 
181
opq_free_elem(opq_elem_t *elem)
 
182
{
 
183
    ipmi_mem_free(elem);
 
184
}
 
185
 
130
186
int
131
 
opq_new_op(opq_t *opq, opq_handler_cb handler, void *cb_data, int nowait)
 
187
opq_new_op_prio(opq_t *opq, opq_handler_cb handler, void *cb_data,
 
188
                int nowait, int prio, opq_elem_t *elem)
132
189
{
133
 
    opq_elem_t *elem;
 
190
    int        success;
134
191
 
135
192
    opq_lock(opq);
136
193
    if (opq->in_handler) {
138
195
            opq_unlock(opq);
139
196
            return -1;
140
197
        }
141
 
        elem = ipmi_mem_alloc(sizeof(*elem));
142
 
        if (!elem)
143
 
            goto out_err;
 
198
        if (!elem) {
 
199
            elem = opq_alloc_elem();
 
200
            if (!elem)
 
201
                goto out_err;
 
202
        }
144
203
        elem->handler = handler;
145
204
        elem->done = NULL;
146
205
        elem->handler_data = cb_data;
147
206
        elem->block = 1;
148
 
        if (! ilist_add_tail(opq->ops, elem, NULL)) {
149
 
            ipmi_mem_free(elem);
150
 
            goto out_err;
151
 
        }
 
207
        if (prio)
 
208
            ilist_add_head(opq->ops, elem, &elem->ilist_item);
 
209
        else
 
210
            ilist_add_tail(opq->ops, elem, &elem->ilist_item);
152
211
        opq->blocked = 0;
153
212
        opq_unlock(opq);
154
213
    } else {
 
214
        if (elem)
 
215
            opq_free_elem(elem);
155
216
        opq->blocked = 0;
156
217
        opq->in_handler = 1;
157
218
        opq->done_handler = NULL;
158
219
        opq_unlock(opq);
159
 
        handler(cb_data, 0);
 
220
        success = handler(cb_data, 0);
 
221
        if (success == OPQ_HANDLER_ABORTED) {
 
222
            /* In case any were added while I was unlocked. */
 
223
            opq_lock(opq);
 
224
            start_next_op(opq);
 
225
            opq_unlock(opq);
 
226
        }
160
227
    }
161
228
 
162
229
    return 1;
167
234
}
168
235
 
169
236
int
 
237
opq_new_op(opq_t *opq, opq_handler_cb handler, void *cb_data, int nowait)
 
238
{
 
239
    return opq_new_op_prio(opq, handler, cb_data, nowait, OPQ_ADD_TAIL, NULL);
 
240
}
 
241
 
 
242
int
170
243
opq_new_op_with_done(opq_t          *opq,
171
244
                     opq_handler_cb handler,
172
245
                     void           *handler_data,
174
247
                     void           *done_data)
175
248
{
176
249
    opq_elem_t *elem;
 
250
    int        success;
177
251
 
178
252
    opq_lock(opq);
179
253
    if (opq->in_handler) {
185
259
        elem->done = done;
186
260
        elem->done_data = done_data;
187
261
        elem->block = opq->blocked;
188
 
        if (! ilist_add_tail(opq->ops, elem, NULL)) {
189
 
            ipmi_mem_free(elem);
190
 
            goto out_err;
191
 
        }
 
262
        ilist_add_tail(opq->ops, elem, &elem->ilist_item);
192
263
        opq->blocked = 0;
193
264
        opq_unlock(opq);
194
265
    } else {
197
268
        opq->done_handler = done;
198
269
        opq->done_data = done_data;
199
270
        opq_unlock(opq);
200
 
        handler(handler_data, 0);
 
271
        success = handler(handler_data, 0);
 
272
        if (success == OPQ_HANDLER_ABORTED) {
 
273
            /* In case any were added while I was unlocked. */
 
274
            opq_lock(opq);
 
275
            start_next_op(opq);
 
276
            opq_unlock(opq);
 
277
        }
201
278
    }
202
279
 
203
280
    return 1;
250
327
        while (list) {
251
328
            next = list->next;
252
329
            list->done(list->done_data, 0);
253
 
            ipmi_mem_free(list);
 
330
            opq_free_elem(list);
254
331
            list = next;
255
332
        }
256
333
 
260
337
        ilist_first(&iter);
261
338
        elem = ilist_get(&iter);
262
339
    }
263
 
    if (elem) {
264
 
        ilist_delete(&iter);
265
 
        opq->done_handler = elem->done;
266
 
        opq->done_data = elem->done_data;
267
 
        opq_unlock(opq);
268
 
        elem->handler(elem->handler_data, 0);
269
 
        ipmi_mem_free(elem);
270
 
    } else {
271
 
        /* The list is empty. */
272
 
        opq->in_handler = 0;
273
 
        opq_unlock(opq);
274
 
    }
 
340
    start_next_op(opq);
 
341
    opq_unlock(opq);
275
342
}
276
343
 
277
344
int