Globus Toolkit 4.0: Asynchronous Event Handling: Example 3
#include <globus_common.h>
#include <stdlib.h>
typedef enum game_state_e
{
FIRST_ROLL,
ROLLING,
LOST_GAME,
WON_GAME
} game_state_t;
typedef struct game_context_s
{
globus_mutex_t mutex;
globus_cond_t cond;
game_state_t state;
int rolls;
int point;
} game_context_t;
void
event_callback(
void * user_arg)
{
int die1;
int die2;
game_context_t * game_context;
game_context = (game_context_t *) user_arg;
die1 = rand() % 6 + 1;
die2 = rand() % 6 + 1;
globus_mutex_lock(&game_context->mutex);
{
game_context->rolls++;
fprintf(stdout, "you rolled %d and %d, total is %d\n",
die1, die2, die1+die2);
switch(game_context->state)
{
case FIRST_ROLL:
if(die1+die2 == 7 || die1+die2 == 11)
{
game_context->state = WON_GAME;
globus_cond_signal(&game_context->cond);
}
else if(die1+die2 == 2 || die1+die2 == 3 || die1+die2 == 12)
{
game_context->state = LOST_GAME;
globus_cond_signal(&game_context->cond);
}
else
{
game_context->state = ROLLING;
game_context->point = die1+die2;
fprintf(stdout, "The point is: %d\n", game_context->point);
globus_callback_register_oneshot(
NULL,
NULL,
event_callback,
game_context);
}
break;
case ROLLING:
if(die1+die2 == 7)
{
game_context->state = LOST_GAME;
globus_cond_signal(&game_context->cond);
}
else if(die1+die2 == game_context->point)
{
game_context->state = WON_GAME;
globus_cond_signal(&game_context->cond);
}
else
{
globus_callback_register_oneshot(
NULL,
NULL,
event_callback,
game_context);
}
break;
default:
globus_assert(0 && "should never reach this state");
break;
}
}
globus_mutex_unlock(&game_context->mutex);
}
int
main(
int argc,
char ** argv)
{
game_context_t game_context;
globus_module_activate(GLOBUS_COMMON_MODULE);
globus_mutex_init(&game_context.mutex, NULL);
globus_cond_init(&game_context.cond, NULL);
game_context.rolls = 0;
game_context.state = FIRST_ROLL;
srandom(time(NULL));
globus_mutex_lock(&game_context.mutex);
{
globus_callback_register_oneshot(
NULL,
NULL,
event_callback,
&game_context);
while(game_context.state != LOST_GAME &&
game_context.state != WON_GAME)
{
globus_cond_wait(&game_context.cond, &game_context.mutex);
}
}
globus_mutex_unlock(&game_context.mutex);
fprintf(stdout, "%s, game over in %d rolls.\n",
game_context.state == LOST_GAME ? "You LOSE" : "You WIN",
game_context.rolls);
globus_module_deactivate(GLOBUS_COMMON_MODULE);
return 0;
}