Commit c1ca641d authored by Pekka Pessi's avatar Pekka Pessi

Added su_clone_pause(), su_clone_resume().

darcs-hash:20060310144605-65a35-0448cd17cc46ea37b34eb84b5a8045ea50adfd85.gz
parent 66f91f40
......@@ -284,7 +284,8 @@ typedef _su_task_t const *_su_task_r;
/* Messages */
#ifndef SU_MSG_ARG_T
/** Default type of su_msg_t message data. Application may define this to
* appropriate type before including <su_wait.h>. */
* appropriate type before including <su_wait.h>.
*/
#define SU_MSG_ARG_T void
#endif
......@@ -445,6 +446,9 @@ void su_clone_forget(su_clone_r);
void su_clone_stop(su_clone_r);
void su_clone_wait(su_root_t *root, su_clone_r clone);
int su_clone_pause(su_clone_r);
int su_clone_resume(su_clone_r);
/* ---------------------------------------------------------------------- */
/* Compatibility */
......
......@@ -53,6 +53,9 @@ typedef struct su_cloned_s {
int *sc_wait;
#if SU_HAVE_PTHREADS
pthread_t sc_tid;
pthread_mutex_t sc_pause[1];
pthread_cond_t sc_resume[1];
int sc_paused;
#endif
} su_cloned_t;
......@@ -920,6 +923,10 @@ static void *su_clone_main(void *varg)
sc->sc_root = self;
sc->sc_tid = pthread_self();
pthread_mutex_init(sc->sc_pause, NULL);
pthread_cond_init(sc->sc_resume, NULL);
pthread_mutex_lock(sc->sc_pause);
if (arg->init && arg->init(self, self->sur_magic) != 0) {
if (arg->deinit)
arg->deinit(self, self->sur_magic);
......@@ -1088,6 +1095,9 @@ int su_clone_start(su_root_t *parent,
sc->sc_root = child;
#if SU_HAVE_PTHREADS
sc->sc_tid = pthread_self();
pthread_mutex_init(sc->sc_pause, NULL);
pthread_cond_init(sc->sc_resume, NULL);
pthread_mutex_lock(sc->sc_pause);
#endif
retval = 0;
} else {
......@@ -1185,6 +1195,77 @@ void su_clone_wait(su_root_t *root, su_clone_r rclone)
}
}
#if SU_HAVE_PTHREADS /* No-op without threads */
static
void su_clone_paused(su_root_magic_t *magic, su_msg_r msg, su_msg_arg_t *arg)
{
su_cloned_t *cloned = *(su_cloned_t **)arg;
assert(cloned);
pthread_cond_wait(cloned->sc_resume, cloned->sc_pause);
}
#endif
/** Pause a clone.
*
* Obtain a exclusive lock on clone's private data.
*
* @retval 0 if successful (and clone is paused)
* @retval -1 upon an error
*/
int su_clone_pause(su_clone_r rclone)
{
#if SU_HAVE_PTHREADS /* No-op without threads */
su_cloned_t *cloned = su_msg_data(rclone);
su_msg_r m = SU_MSG_RINITIALIZER;
if (!cloned)
return (errno = EFAULT), -1;
if (pthread_equal(pthread_self(), cloned->sc_tid))
return 0;
if (su_msg_create(m, su_clone_task(rclone), su_task_null,
su_clone_paused, sizeof cloned) < 0)
return -1;
*(su_cloned_t **)su_msg_data(m) = cloned;
if (su_msg_send(m) < 0)
return -1;
if (pthread_mutex_lock(cloned->sc_pause) < 0)
return -1;
pthread_cond_signal(cloned->sc_resume);
#endif
return 0;
}
/** Resume a clone.
*
* Give up a exclusive lock on clone's private data.
*
* @retval 0 if successful (and clone is resumed)
* @retval -1 upon an error
*/
int su_clone_resume(su_clone_r rclone)
{
#if SU_HAVE_PTHREADS /* No-op without threads */
su_cloned_t *cloned = su_msg_data(rclone);
if (!cloned)
return (errno = EFAULT), -1;
if (pthread_equal(pthread_self(), cloned->sc_tid))
return 0;
if (pthread_mutex_unlock(cloned->sc_pause) < 0)
return -1;
#endif
return 0;
}
/* =========================================================================
* Messages
......@@ -1224,10 +1305,10 @@ int su_msg_create(su_msg_r rmsg,
msg->sum_func = wakeup;
*rmsg = msg;
return 0;
} else {
*rmsg = NULL;
return -1;
}
}
*rmsg = NULL;
return -1;
}
/** Add a report function to a message
......
......@@ -345,7 +345,7 @@ start_pong(struct pinger *p, su_msg_r msg, su_sockaddr_t *arg)
su_msg_send(reply);
}
else {
fprintf(stderr, "su_msg_create failed!\n");
fprintf(stderr, "su_msg_reply failed!\n");
}
}
......@@ -468,7 +468,7 @@ int main(int argc, char *argv[])
root = su_root_create(NULL);
if (!root) perror("su_root_create"), exit(1);
su_root_threading(root, 0 && !opt_singlethread);
su_root_threading(root, !opt_singlethread);
if (su_clone_start(root, ping, &pinger, do_init, do_destroy) != 0)
perror("su_clone_start"), exit(1);
......@@ -481,10 +481,16 @@ int main(int argc, char *argv[])
su_perror("su_timer_create"), exit(1);
su_timer_set(t, (su_timer_f)do_exit, NULL);
su_clone_pause(ping);
su_clone_pause(pong);
su_msg_create(start_msg, su_clone_task(ping), su_clone_task(pong),
init_ping, 0);
su_msg_send(start_msg);
su_clone_resume(ping);
su_clone_resume(pong);
su_root_run(root);
su_clone_wait(root, ping);
......
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