Commit eea968de authored by Pekka Pessi's avatar Pekka Pessi
Browse files

su_root.c: fixed truncation in su_task_cmp(), refactored su_task_execute().

Updated documentation.

darcs-hash:20060925181808-65a35-447aab5c4c4c258105dfdb1d507ff954eb61f001.gz
parent 99846881
...@@ -236,15 +236,23 @@ void su_task_move(su_task_r dst, su_task_r src) ...@@ -236,15 +236,23 @@ void su_task_move(su_task_r dst, su_task_r src)
* @param a First task * @param a First task
* @param b Second task * @param b Second task
* *
* @return * @retval negative number, if a < b
* The function @c su_task_cmp() returns negative number, if a < b, * @retval positive number, if a > b
* positive number, if a > b, and 0, if a == b. * @retval 0, if a == b.
*/ */
int su_task_cmp(su_task_r const a, su_task_r const b) int su_task_cmp(su_task_r const a, su_task_r const b)
{ {
int retval = a->sut_port - b->sut_port; intptr_t retval = a->sut_port - b->sut_port;
retval = retval ? retval : (char *)a->sut_root - (char *)b->sut_root;
if (sizeof(retval) != sizeof(int)) {
if (retval < 0)
retval = -1;
else if (retval > 0)
retval = 1;
}
return retval ? retval : (char *)a->sut_root - (char *)b->sut_root; return (int)retval;
} }
/** /**
...@@ -288,8 +296,8 @@ int su_task_attach(su_task_r self, su_root_t *root) ...@@ -288,8 +296,8 @@ int su_task_attach(su_task_r self, su_root_t *root)
* @param self task handle * @param self task handle
* *
* @return * @return
* The function @c su_task_root() returns a pointer to root object attached * A pointer to root object attached to the task handle, or NULL if no root
* to the task handle, or NULL if no root object has been attached. * object has been attached.
*/ */
su_root_t *su_task_root(su_task_r const self) su_root_t *su_task_root(su_task_r const self)
{ {
...@@ -313,8 +321,8 @@ int su_task_detach(su_task_r self) ...@@ -313,8 +321,8 @@ int su_task_detach(su_task_r self)
* *
* @param task task handle * @param task task handle
* *
* @return The function @c su_task_timers() returns a timer list of the * @return A timer list of the task. If there are no timers, it returns
* task. If there are no timers, it returns NULL. * NULL.
*/ */
su_timer_t **su_task_timers(su_task_r const task) su_timer_t **su_task_timers(su_task_r const task)
{ {
...@@ -329,7 +337,7 @@ struct su_task_execute ...@@ -329,7 +337,7 @@ struct su_task_execute
pthread_cond_t cond[1]; pthread_cond_t cond[1];
int (*function)(void *); int (*function)(void *);
void *arg; void *arg;
int *return_value; int value;
}; };
static void _su_task_execute(su_root_magic_t *m, static void _su_task_execute(su_root_magic_t *m,
...@@ -338,7 +346,8 @@ static void _su_task_execute(su_root_magic_t *m, ...@@ -338,7 +346,8 @@ static void _su_task_execute(su_root_magic_t *m,
{ {
struct su_task_execute *frame = *(struct su_task_execute **)a; struct su_task_execute *frame = *(struct su_task_execute **)a;
pthread_mutex_lock(frame->mutex); pthread_mutex_lock(frame->mutex);
*frame->return_value = frame->function(frame->arg); frame->value = frame->function(frame->arg);
frame->function = NULL; /* Mark as completed */
pthread_cond_signal(frame->cond); pthread_cond_signal(frame->cond);
pthread_mutex_unlock(frame->mutex); pthread_mutex_unlock(frame->mutex);
} }
...@@ -354,48 +363,55 @@ int su_task_execute(su_task_r const task, ...@@ -354,48 +363,55 @@ int su_task_execute(su_task_r const task,
int (*function)(void *), void *arg, int (*function)(void *), void *arg,
int *return_value) int *return_value)
{ {
int value; if (function == NULL)
return (errno = EFAULT), -1;
if (!su_port_own_thread(task->sut_port)) { if (!su_port_own_thread(task->sut_port)) {
#if SU_HAVE_PTHREADS #if SU_HAVE_PTHREADS
int success;
su_msg_r m = SU_MSG_R_INIT; su_msg_r m = SU_MSG_R_INIT;
struct su_task_execute frame; struct su_task_execute frame = {
{ PTHREAD_MUTEX_INITIALIZER },
{ PTHREAD_COND_INITIALIZER },
function, arg, 0
};
if (su_msg_create(m, task, su_task_null, if (su_msg_create(m, task, su_task_null,
_su_task_execute, (sizeof &frame)) < 0) _su_task_execute, (sizeof &frame)) < 0)
return -1; return -1;
*(struct su_task_execute **)su_msg_data(m) = &frame; *(struct su_task_execute **)su_msg_data(m) = &frame;
pthread_mutex_init(frame.mutex, NULL);
pthread_cond_init(frame.cond, NULL);
frame.function = function;
frame.arg = arg;
frame.return_value = &value;
pthread_mutex_lock(frame.mutex); pthread_mutex_lock(frame.mutex);
if (su_msg_send(m) < 0) { success = su_msg_send(m);
su_msg_destroy(m);
pthread_mutex_unlock(frame.mutex); if (success == 0)
pthread_mutex_destroy(frame.mutex); while (frame.function)
pthread_cond_destroy(frame.cond); pthread_cond_wait(frame.cond, frame.mutex);
return -1; else
} su_msg_destroy(m);
pthread_cond_wait(frame.cond, frame.mutex); pthread_mutex_unlock(frame.mutex);
pthread_mutex_destroy(frame.mutex); pthread_mutex_destroy(frame.mutex);
pthread_cond_destroy(frame.cond); pthread_cond_destroy(frame.cond);
if (return_value)
*return_value = frame.value;
return success;
#else #else
return -1; return (errno = ENOSYS), -1;
#endif #endif
} }
else else {
value = function(arg); int value = function(arg);
if (return_value)
*return_value = value;
return 0; if (return_value)
*return_value = value;
return 0;
}
} }
_su_task_r su_task_new(su_task_r task, su_root_t *root, su_port_t *port); _su_task_r su_task_new(su_task_r task, su_root_t *root, su_port_t *port);
......
Markdown is supported
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