I have one school assignment in which I shall implement one game based on client-server architecture. The server side controls all of the game, and the client side has just an image of what is going on. One of the features of the server is to kick out clients from the game, and here comes the problem.
I have one thread on client to receive messages from the server and the main thread receives input from the user, but when the first thread receives shutdown comand, the main thread is waiting for one key from the client before executing the shutdown.
My question is : is there any way to unblock the wgetch on the main thread to make it not stay waiting for a key and execute the shutdown ?
Code :
void *trata_fifo(void *dados) {
int i;
RESPONSE resp;
char namepipe[MAX];
sprintf(namepipe, CLIENT_FIFO, getpid());
mkfifo(namepipe, 0600);
fd_res = open(namepipe, O_RDWR);
do {
i = read(fd_res, &resp, sizeof (RESPONSE));
drawGame(resp);
if (resp.command == 3) {
wclear(info_win);
box(info_win, 0, 0);
wattron(info_win, A_REVERSE | A_BOLD);
mvwprintw(info_win, 2, 4, "Score");
mvwprintw(info_win, 4, 5, " %d ", resp.points);
mvwprintw(info_win, 6, 2, "Bombinhas");
mvwprintw(info_win, 8, 5, " %d ", resp.bombinha);
mvwprintw(info_win, 10, 2, "Megabombas");
mvwprintw(info_win, 12, 5, " %d ", resp.megaBomba);
wrefresh(info_win);
}
if (resp.command == 4) {//here
SHUTDOWN = true;
write(STDIN_FILENO,NULL,0);//i tried this , but its not working
}
if (resp.command == 5) {
SHUTDOWN = true;
}
}
} while (!SHUTDOWN);
close(fd_res);
pthread_exit(NULL);
}
int main() {
REQUEST client;
pthread_t tarefa;
int highlight = 1, choice = 0, opt;
int startx = 0, starty = 0;
signal(SIGINT, handleSignalCli);
signal(SIGUSR1, handleSignalCli);
signal(SIGALRM, handleSignalCli);
if (access(SERVER_FIFO, F_OK) != 0) //Verificar se servidor esta correndo
{
perror("[ERROR] Server ins't running...!/n");
exit(EXIT_FAILURE);
}
if (pthread_create(&tarefa, NULL, trata_fifo, NULL) != 0) {
fprintf(stderr, "[ERROR] Creating Thread\n");
exit(EXIT_FAILURE);
}
fd = open(SERVER_FIFO, O_WRONLY);
if (!fd) {
perror("[ERROR] Opening Server Fifo...!\n");
exit(EXIT_FAILURE);
}
/*...*/
while (!SHUTDOWN) {
cbreak();
keypad(game_win, TRUE);
noecho();
client.command = 3;
client.tecla = wgetch(game_win);
res = write(fd, &client, sizeof (client));
}
close(fd);
pthread_join(tarefa, NULL);
delwin(game_win);
delwin(main_win);
endwin();
exit(0);
}
PS:resp.comand = 4 means server is kicking out the player/client. Sorry for bad english :)
In curses, you have three choices
wtimeout
nodelay
Both of those (wtimeout
and nodelay
) are set on the given window, and can be modified as needed. A wgetch
on a different window is unaffected.
For example, to use non-blocking reads for game_win
, you could add this near the keypad
call:
nodelay(game_win, TRUE);