Commit d44882a8 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Corrected allocation order in encoder and decoder.

Fixed recursion bug in scheduler.
parent 2270c9ec
...@@ -37,6 +37,7 @@ struct sample_entry { ...@@ -37,6 +37,7 @@ struct sample_entry {
struct labcomm_decoder { struct labcomm_decoder {
struct labcomm_reader *reader; struct labcomm_reader *reader;
int reader_allocated;
struct labcomm_error_handler *error; struct labcomm_error_handler *error;
struct labcomm_memory *memory; struct labcomm_memory *memory;
struct labcomm_scheduler *scheduler; struct labcomm_scheduler *scheduler;
...@@ -63,6 +64,7 @@ struct labcomm_decoder *labcomm_decoder_new( ...@@ -63,6 +64,7 @@ struct labcomm_decoder *labcomm_decoder_new(
result->reader->count = 0; result->reader->count = 0;
result->reader->pos = 0; result->reader->pos = 0;
result->reader->error = 0; result->reader->error = 0;
result->reader_allocated = 0;
result->error = error; result->error = error;
result->memory = memory; result->memory = memory;
result->scheduler = scheduler; result->scheduler = scheduler;
...@@ -264,10 +266,11 @@ static void call_handler(void *value, void *context) ...@@ -264,10 +266,11 @@ static void call_handler(void *value, void *context)
labcomm_reader_end(wrap->reader, wrap->reader->action_context); labcomm_reader_end(wrap->reader, wrap->reader->action_context);
} }
static void reader_alloc(struct labcomm_reader *reader) static void reader_alloc(struct labcomm_decoder *d)
{ {
if (reader->data == NULL) { if (!d->reader_allocated) {
labcomm_reader_alloc(reader, reader->action_context, d->reader_allocated = 1;
labcomm_reader_alloc(d->reader, d->reader->action_context,
LABCOMM_VERSION); LABCOMM_VERSION);
} }
} }
...@@ -276,7 +279,7 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) ...@@ -276,7 +279,7 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d)
{ {
int result, remote_index; int result, remote_index;
reader_alloc(d->reader); reader_alloc(d);
remote_index = labcomm_read_packed32(d->reader); remote_index = labcomm_read_packed32(d->reader);
if (d->reader->error < 0) { if (d->reader->error < 0) {
result = d->reader->error; result = d->reader->error;
...@@ -377,7 +380,7 @@ int labcomm_internal_decoder_register( ...@@ -377,7 +380,7 @@ int labcomm_internal_decoder_register(
int local_index; int local_index;
struct sample_entry *entry; struct sample_entry *entry;
reader_alloc(d->reader); reader_alloc(d);
local_index = labcomm_signature_local_index(signature); local_index = labcomm_signature_local_index(signature);
if (local_index <= 0) { goto out; } if (local_index <= 0) { goto out; }
labcomm_reader_start(d->reader, d->reader->action_context, labcomm_reader_start(d->reader, d->reader->action_context,
......
...@@ -55,6 +55,8 @@ struct labcomm_encoder *labcomm_encoder_new( ...@@ -55,6 +55,8 @@ struct labcomm_encoder *labcomm_encoder_new(
result->memory = memory; result->memory = memory;
result->scheduler = scheduler; result->scheduler = scheduler;
LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int); LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
labcomm_writer_alloc(result->writer,
result->writer->action_context, LABCOMM_VERSION);
} }
return result; return result;
} }
...@@ -78,9 +80,6 @@ int labcomm_internal_encoder_register( ...@@ -78,9 +80,6 @@ int labcomm_internal_encoder_register(
index = labcomm_signature_local_index(signature); index = labcomm_signature_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler); labcomm_scheduler_writer_lock(e->scheduler);
if (e->writer->data == NULL) {
labcomm_writer_alloc(e->writer,e->writer->action_context, LABCOMM_VERSION);
}
if (signature->type != LABCOMM_SAMPLE) { goto out; } if (signature->type != LABCOMM_SAMPLE) { goto out; }
if (index <= 0) { goto out; } if (index <= 0) { goto out; }
done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index); done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
...@@ -118,9 +117,6 @@ int labcomm_internal_encode( ...@@ -118,9 +117,6 @@ int labcomm_internal_encode(
index = labcomm_signature_local_index(signature); index = labcomm_signature_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler); labcomm_scheduler_writer_lock(e->scheduler);
if (e->writer->data == NULL) {
labcomm_writer_alloc(e->writer,e->writer->action_context, LABCOMM_VERSION);
}
result = labcomm_writer_start(e->writer, e->writer->action_context, result = labcomm_writer_start(e->writer, e->writer->action_context,
index, signature, value); index, signature, value);
if (result == -EALREADY) { result = 0; goto no_end; } if (result == -EALREADY) { result = 0; goto no_end; }
...@@ -162,61 +158,11 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, ...@@ -162,61 +158,11 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
uint32_t action, va_list va) uint32_t action, va_list va)
{ {
int result = -ENOTSUP; int result = -ENOTSUP;
int index;
index = labcomm_signature_local_index(signature);
result = labcomm_writer_ioctl(encoder->writer, result = labcomm_writer_ioctl(encoder->writer,
encoder->writer->action_context, encoder->writer->action_context,
-1, signature, action, va); index, signature, action, va);
return result; return result;
} }
#if 0
static struct labcomm_encoder *enter_encoder(struct labcomm_encoder *e)
{
if (e->is_deferred) {
return e->is_deferred;
} else {
labcomm_lock_acquire(e->lock);
e->waiting++;
while (e->busy) { labcomm_lock_wait(e->lock, 10000000); }
e->busy = 1;
labcomm_lock_release(e->lock);
if (e->writer->data == NULL) {
labcomm_writer_alloc(e->writer,e->writer->action_context,
e, LABCOMM_VERSION, encoder_enqueue_action);
if (e->alloc_action) {
struct labcomm_encoder deferred;
struct encoder_alloc_action *p;
deferred.is_deferred = e;
p = e->alloc_action;
e->alloc_action = NULL;
while (p) {
struct encoder_alloc_action *tmp;
p->action(&deferred, p->context);
tmp = p;
p = p->next;
labcomm_memory_free(e->memory, 1, tmp);
}
}
}
}
return e;
}
static void leave_encoder(struct labcomm_encoder *e)
{
if (!e->is_deferred) {
labcomm_lock_acquire(e->lock); {
e->busy = 0;
e->waiting--;
if (e->waiting) {
labcomm_lock_notify(e->lock);
}
} labcomm_lock_release(e->lock);
}
}
#endif
...@@ -48,6 +48,7 @@ struct pthread_scheduler { ...@@ -48,6 +48,7 @@ struct pthread_scheduler {
pthread_mutex_t writer_mutex; pthread_mutex_t writer_mutex;
pthread_mutex_t data_mutex; pthread_mutex_t data_mutex;
pthread_cond_t data_cond; pthread_cond_t data_cond;
int running_deferred;
struct pthread_deferred deferred; struct pthread_deferred deferred;
struct pthread_deferred deferred_with_delay; struct pthread_deferred deferred_with_delay;
}; };
...@@ -137,6 +138,7 @@ static struct labcomm_time_action time_action = { ...@@ -137,6 +138,7 @@ static struct labcomm_time_action time_action = {
static int run_action(struct pthread_scheduler *scheduler, static int run_action(struct pthread_scheduler *scheduler,
struct pthread_deferred *element) struct pthread_deferred *element)
{ {
/* Called with data_lock held */
element->prev->next = element->next; element->prev->next = element->next;
element->next->prev = element->prev; element->next->prev = element->prev;
labcomm_scheduler_data_unlock(&scheduler->scheduler); labcomm_scheduler_data_unlock(&scheduler->scheduler);
...@@ -148,6 +150,9 @@ static int run_action(struct pthread_scheduler *scheduler, ...@@ -148,6 +150,9 @@ static int run_action(struct pthread_scheduler *scheduler,
static int run_deferred(struct pthread_scheduler *scheduler) static int run_deferred(struct pthread_scheduler *scheduler)
{ {
/* Called with data_lock held */
if (scheduler->running_deferred) { goto out; }
scheduler->running_deferred = 1;
while (!queue_empty(&scheduler->deferred)) { while (!queue_empty(&scheduler->deferred)) {
run_action(scheduler, scheduler->deferred.next); run_action(scheduler, scheduler->deferred.next);
} }
...@@ -160,6 +165,8 @@ static int run_deferred(struct pthread_scheduler *scheduler) ...@@ -160,6 +165,8 @@ static int run_deferred(struct pthread_scheduler *scheduler)
run_action(scheduler, scheduler->deferred_with_delay.next); run_action(scheduler, scheduler->deferred_with_delay.next);
} }
} }
scheduler->running_deferred = 0;
out:
return 0; return 0;
} }
...@@ -359,6 +366,7 @@ struct labcomm_scheduler *labcomm_pthread_scheduler_new( ...@@ -359,6 +366,7 @@ struct labcomm_scheduler *labcomm_pthread_scheduler_new(
if (pthread_cond_init(&scheduler->data_cond, NULL) != 0) { if (pthread_cond_init(&scheduler->data_cond, NULL) != 0) {
goto destroy_data_mutex; goto destroy_data_mutex;
} }
scheduler->running_deferred = 0;
scheduler->deferred.next = &scheduler->deferred; scheduler->deferred.next = &scheduler->deferred;
scheduler->deferred.prev = &scheduler->deferred; scheduler->deferred.prev = &scheduler->deferred;
scheduler->deferred_with_delay.next = &scheduler->deferred_with_delay; scheduler->deferred_with_delay.next = &scheduler->deferred_with_delay;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment