Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy can I not get system V message queues working with fork()?
    text
    copied!<p>I have a program here: </p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/ipc.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/msg.h&gt; #include &lt;sys/wait.h&gt; #include &lt;errno.h&gt; #include "linkedlist.h" #include "globals.h" #include "card.h" #include "logging.h" #include "stack.h" #include "servers.h" #include "player.h" #define VERSION "0.1" #define ERR -1 /* * Main function runs, loads 5 named table objects. For each table * created a fork is created for that specific table object that * allows each table to run independently. * * Usernames details are also created and prepared. These are hardcoded * until I add database logic later. * * After the tables are prepared, the main function starts a server * listening thread that waits for UNIX sockets to connect to it. When * they arrive it spawns a handling thread that does a quick login check * and then asks the user which of the named tables they want to play on * * The socket information is then connected to the table, so the table can * then communicate with user. When the table is full, the table algorithm * is responcible for basically looping contineously, creating new "games" * until only one player is left. He is the winner. When he wins, the table * exits. * * the game loop does all the real work for the texas holdem game, hosting * rounds of bets, dealing cards etc. */ void table_process(int tables_id); void main_game_loop(void); int main(int argc, char **argv) { int main_process_id; int connection_process_id; char table_config_name[8]; char *table_name; stack *my_deck; card *current_card; int i; int s; printf("------------ PRT POKER -----------\nA texas holdem poker server\n~~~~Version: %s~~~~~~~\n", VERSION); config_load("poker.conf"); logging_init(); if (key = ftok("/mnt/mydocuments/git/texas_holdem/poker", 'a') == -1) { logging_critical("Call to ftok failed"); exit(1); } // if ((msg_queue = msgget(key, 0644 | IPC_CREAT)) == -1) // { // logging_critical("call to msgget failed"); // exit(1); // } //read int the list of tables from the configuration file config_get_int("players_per_table", &amp;player_count); logging_info("players per table: %i", *player_count); config_get_int("table_count", &amp;table_count); logging_info("number of tables: %i", *table_count); table_names = malloc(sizeof(char*) * (*table_count)); logging_info("Table count: %d", *table_count); for (i = 0; i &lt; *table_count; i++) { sprintf(table_config_name, "table_%d", (i + 1)); config_get_string(table_config_name, &amp;table_name); table_names[i] = table_name; logging_info("Created table %d: %s", i, table_name); if (fork() == 0) { table_process(i); _exit(0); } } main_process_id = getpid(); connection_process_id = fork(); logging_info("connecton process: %d", connection_process_id); if (connection_process_id == 0) { wait_for_players(); _exit(0); } else waitpid(connection_process_id, &amp;s, 0); logging_info("Application ended"); return 0; } void table_process(int table_id) { linkedlist *players; player *p; int players_added; if ((msg_queue = msgget(key, 0644 | IPC_CREAT)) == -1) { logging_critical("call to msgget failed"); exit(1); } logging_info("table %s (%i) running in process %d", table_names[table_id], table_id, getpid()); players = linkedlist_new(); players_added = *player_count; while (players_added &gt; 0) { logging_info("still waiting for %i players to join %s with queue id %i", players_added, table_names[table_id], table_id + MSG_QUEUE_OFFSET); //THIS DOESN'T WORK!!!! IT DOESN'T WAKE UP if (msgrcv(msg_queue, &amp;p, sizeof(player), table_id + MSG_QUEUE_OFFSET, 0) == -1) { logging_critical("recieving from message queue failed"); _exit(1); } else logging_info("played joined %s", table_names[table_id]); logging_debug("player = %s, %s", p-&gt;name, p-&gt;password); players_added--; } logging_info("table %s ready to start!!!!!", table_names[table_id]); } void main_game_loop(void) { logging_debug("main_game_loop"); } </code></pre> <p>The program is supposed to start and fork into 4 threads. The first three threads call msgget() to create a system V message queue.</p> <p>Then they all call msgrcv() and wait for a different id to occur.</p> <p>The fourth thread listens for connecting clients and then invokes msgsnd(). For some reason, none of the forks waiting for a message awake again.</p> <ol> <li><p>I'm sure the message queue is correct. </p></li> <li><p>I have a print statement before msgsrcv so I can see that see that the fork happens correctly for each statement. There is also a print statement afterwards so I can see the code doesn't pass it.</p></li> <li><p>I have run ipcs from the command prompt.</p></li> <li><p>There is definitely a message queue created and definetly has a message in it.</p></li> <li><p>If I change the msgrcv to say "0" then one of the threads will wake up but that's not the behaviour I want.</p></li> <li><p>msgget() doesn't throw an error. </p></li> <li><p>msgsnd() didn't throw an error.</p></li> <li><p>I'm positive the id in the structure is correct.</p></li> </ol> <p>Any ideas what I am doing wrong?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload