-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmsgs.c
More file actions
100 lines (76 loc) · 2.79 KB
/
msgs.c
File metadata and controls
100 lines (76 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <stdio.h> // fprintf
#include <setjmp.h> // siglongjmp
#include <sys/types.h> // key_t
#include <sys/ipc.h> // ftok
#include <signal.h> // SIGUSR1
#include "tools.h"
#include "game.h" // sGame
#include "sigmsg.h" // sigmsg*
#include "longjump.h" // long jump stuff
#include "msgs.h"
sMsg last_msg;
unsigned int last_msg_datasz;
void msgs_handler(int sig, sMsg *msg /* in the shm */, unsigned int datasz, sGame *g) {
sGameConf *conf = game_get_conf(g, NULL);
sGameState *state = game_get_state(g, NULL);
memcpy(&last_msg, msg, datasz); // make a copy because out of this handler, the shm may be modified
datasz-=sizeof(eMsgsTypes); // datasz will only be the size of the payload
last_msg_datasz=datasz;
switch(msg->type) {
case MSG_JOIN:{ // no payload
// prepare and send answer to sender
sGameInit *init=(sGameInit *)msg->data;
memcpy(&init->conf, conf, sizeof(*conf));
memcpy(&init->st, state, sizeof(*state));
msg->type=MSG_INITST8;
msg_answer(msg, sizeof(*init));
break;} // never reached
case MSG_READY: // payload is sGameConf
game_set_conf(g, (sGameConf *)msg->data);
msg->type=MSG_START;
msg_answer(msg, 0); // no payload
case MSG_TURN: // payload is sGameTurn
case MSG_PAUSE: // no payload
case MSG_RESUME: // payload is the remaining time stored in an int
case MSG_END: // 1 char payload (0 or 1 to choose if you should delete the histo file)
sigmsgunlock(); // if we don't return from this isr, we have to unlock the shm
siglongjmp(jumpenv, LJUMP_ISR); // let's stop what we are doing
break; // never reached
default:
fprintf(stderr, "Unhandled message %d\n", msg->type);
break;
}
}
int msg_ctl(sGame *g, int cmd, struct sigmsgid_ds *buf) {
key_t key;
if((key=ftok(game_get_filepath(g), 0))==(key_t)-1)
return -1;
return sigmsgctl(key, cmd, buf);
}
int msg_init(sGame *g, int create) {
key_t key;
if((key=ftok(game_get_filepath(g), 0))==(key_t)-1)
return -1;
if(sigmsginit(key, 0600|(create?(IPC_CREAT|IPC_EXCL):0))==-1)
return -1;
if(sigmsgreg(SIGUSR1, (sigmsghnd)msgs_handler, (void *)g)==-1)
return -1;
return 0;
}
int msg_send(sMsg *msg, unsigned int datasz) {
return sigmsgsend(SIGUSR1, (const void *)msg, datasz+sizeof(eMsgsTypes));
}
int msg_transfer(sMsg *msg, unsigned int *datasz) {
int ret;
(*datasz)+=sizeof(eMsgsTypes);
ret=sigmsgtrans(SIGUSR1, (void *)msg, datasz);
if(*datasz)
(*datasz)-=sizeof(eMsgsTypes);
return ret;
}
int msg_answer(sMsg *msg, unsigned int datasz) {
return sigmsgans((const void *)msg, datasz+sizeof(eMsgsTypes));
}
int msg_deinit(int destroy) {
return sigmsgdeinit(destroy);
}