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)
* @param a First task
* @param b Second task
*
* @return
* The function @c su_task_cmp() returns negative number, if a < b,
* positive number, if a > b, and 0, if a == b.
* @retval negative number, if a < b
* @retval positive number, if a > b
* @retval 0, if a == 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)
* @param self task handle
*
* @return
* The function @c su_task_root() returns a pointer to root object attached
* to the task handle, or NULL if no root object has been attached.
* A pointer to root object attached to the task handle, or NULL if no root
* object has been attached.
*/
su_root_t *su_task_root(su_task_r const self)
{
......@@ -313,8 +321,8 @@ int su_task_detach(su_task_r self)
*
* @param task task handle
*
* @return The function @c su_task_timers() returns a timer list of the
* task. If there are no timers, it returns NULL.
* @return A timer list of the task. If there are no timers, it returns
* NULL.
*/
su_timer_t **su_task_timers(su_task_r const task)
{
......@@ -329,7 +337,7 @@ struct su_task_execute
pthread_cond_t cond[1];
int (*function)(void *);
void *arg;
int *return_value;
int value;
};
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;
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_mutex_unlock(frame->mutex);
}
......@@ -354,48 +363,55 @@ int su_task_execute(su_task_r const task,
int (*function)(void *), void *arg,
int *return_value)
{
int value;
if (function == NULL)
return (errno = EFAULT), -1;
if (!su_port_own_thread(task->sut_port)) {
#if SU_HAVE_PTHREADS
int success;
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,
_su_task_execute, (sizeof &frame)) < 0)
return -1;
*(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);
if (su_msg_send(m) < 0) {
success = su_msg_send(m);
if (success == 0)
while (frame.function)
pthread_cond_wait(frame.cond, frame.mutex);
else
su_msg_destroy(m);
pthread_mutex_unlock(frame.mutex);
pthread_mutex_destroy(frame.mutex);
pthread_cond_destroy(frame.cond);
return -1;
}
pthread_cond_wait(frame.cond, frame.mutex);
pthread_mutex_destroy(frame.mutex);
pthread_cond_destroy(frame.cond);
if (return_value)
*return_value = frame.value;
return success;
#else
return -1;
return (errno = ENOSYS), -1;
#endif
}
else
value = function(arg);
else {
int value = function(arg);
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);
......
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