vici: Support thread cancellation in command callbacks

This commit is contained in:
Martin Willi 2014-02-11 15:09:08 +01:00
parent 045bdf5283
commit ecc4b51048
2 changed files with 53 additions and 19 deletions

View File

@ -20,6 +20,7 @@
#include <bio/bio_writer.h>
#include <threading/mutex.h>
#include <threading/condvar.h>
#include <threading/thread.h>
#include <collections/array.h>
#include <collections/hashtable.h>
@ -184,40 +185,69 @@ static void unregister_event(private_vici_dispatcher_t *this, char *name,
}
}
/**
* Data to release on thread cancellation
*/
typedef struct {
private_vici_dispatcher_t *this;
command_t *cmd;
vici_message_t *request;
} release_data_t;
/**
* Release command after execution/cancellation
*/
CALLBACK(release_command, void,
release_data_t *release)
{
release->request->destroy(release->request);
release->this->mutex->lock(release->this->mutex);
if (--release->cmd->uses == 0)
{
release->this->cond->broadcast(release->this->cond);
}
release->this->mutex->unlock(release->this->mutex);
free(release);
}
/**
* Process a request message
*/
void process_request(private_vici_dispatcher_t *this, char *name, u_int id,
chunk_t data)
{
command_t *cmd;
vici_message_t *request, *response = NULL;
vici_message_t *response = NULL;
release_data_t *release;
INIT(release,
.this = this,
);
this->mutex->lock(this->mutex);
cmd = this->cmds->get(this->cmds, name);
if (cmd)
release->cmd = this->cmds->get(this->cmds, name);
if (release->cmd)
{
cmd->uses++;
release->cmd->uses++;
}
this->mutex->unlock(this->mutex);
if (cmd)
if (release->cmd)
{
request = vici_message_create_from_data(data, FALSE);
response = cmd->cb(cmd->user, cmd->name, id, request);
request->destroy(request);
thread_cleanup_push(release_command, release);
this->mutex->lock(this->mutex);
if (--cmd->uses == 0)
release->request = vici_message_create_from_data(data, FALSE);
response = release->cmd->cb(release->cmd->user, release->cmd->name,
id, release->request);
thread_cleanup_pop(TRUE);
if (response)
{
this->cond->broadcast(this->cond);
send_op(this, id, VICI_CMD_RESPONSE, NULL, response);
response->destroy(response);
}
this->mutex->unlock(this->mutex);
}
if (response)
{
send_op(this, id, VICI_CMD_RESPONSE, NULL, response);
response->destroy(response);
}
else
{
@ -264,7 +294,9 @@ CALLBACK(inbound, void,
if (reader->read_data8(reader, &chunk) &&
vici_stringify(chunk, name, sizeof(name)))
{
thread_cleanup_push((void*)reader->destroy, reader);
process_request(this, name, id, reader->peek(reader));
thread_cleanup_pop(FALSE);
}
else
{

View File

@ -18,6 +18,7 @@
#include <daemon.h>
#include <threading/mutex.h>
#include <threading/rwlock.h>
#include <threading/thread.h>
#include <collections/array.h>
#include <collections/linked_list.h>
#include <processing/jobs/callback_job.h>
@ -374,8 +375,9 @@ CALLBACK(on_read, bool,
if (data.len)
{
thread_cleanup_push(free, data.ptr);
entry->this->inbound(entry->this->user, entry->id, data);
chunk_clear(&data);
thread_cleanup_pop(TRUE);
}
return ret;