Professional Web Applications Themes

message queues and pthreads - UNIX Programming

Hello, this is my first time programming with pthreads and message queues. I am using sys/msg.h for the message queues. My client program is able to connect and disconnect from the server no problem. But, when I add in a message queue the server just hangs. The server sets up the receiving thread, pops off another for the sending and then uses recv (blocking) to wait for more info from the client. But, when I send the quit signal from the client, the server doesn't even acknowledge that the data has been sent. The server just sits their. It almost ...

  1. #1

    Default message queues and pthreads

    Hello,
    this is my first time programming with pthreads and message queues.
    I am using sys/msg.h for the message queues.

    My client program is able to connect and disconnect from the server
    no problem. But, when I add in a message queue the server just hangs.

    The server sets up the receiving thread, pops off another for the
    sending and then uses recv (blocking) to wait for more info from the client.

    But, when I send the quit signal from the client, the server doesn't
    even acknowledge that the data has been sent. The server just sits their.

    It almost seems as though the send thread is blocking the recieve thread.

    Here is the relevent code:

    SERVER:
    RECIEVE THREAD
    /* and we pop off a thread for the back connect */
    fprintf(stderr, "pop off the thread\n");
    if (pthread_create(&users_logged_in[number_users_logged_in -
    1].send_tid, &pthread_attr, launch_cas_s, (void*)&passed) != 0) {
    fprintf(stderr, "can't get send thread going\n");
    if (send(csocket, (const void*)"0", (size_t)1, NULL) <= 0) {
    fprintf(stderr, "problem send err code\n");
    }
    close(csocket);
    number_users_logged_in--;
    tmp = (struct Users *)realloc((void*)users_logged_in,
    number_users_logged_in*sizeof(struct Users));
    if (tmp == NULL) {
    fprintf(stderr, "horrible things are happening\n");
    }
    users_logged_in = tmp;

    pthread_exit(NULL);
    }

    fprintf(stderr, "successful login\n");
    if (send(csocket, (const void*)"1", (size_t)1, NULL) <= 0) {
    fprintf(stderr, "problem sending success code\n");
    close(csocket);
    pthread_exit(NULL);
    }

    /* here is the game loop */
    fprintf(stderr, "everything went as planned - starting loop\n");
    do {
    /* this is where is "hangs" here */
    fprintf(stderr, "WAITING FOR DATA\n");

    ret = recv(csocket, (void*)r_c, sizeof(char), NULL);
    fprintf(stderr, "got something\n");
    if (ret < 0) {
    fprintf(stderr, "error occured\n");
    }
    fprintf(stderr, "ret %d == got %s\n", ret, r_c);
    if ((ret = strncmp(r_c, "-", 1)) == 0) {
    keep_going = 1;
    } else {
    /* this is where everything happens */
    r_i = atoi(r_c);
    fprintf(stderr, "everything happens here, got %d\n", r_i);
    }
    } while (keep_going == 0);

    SEND THREAD
    /* we now init the message queue */
    fprintf(stderr, "setting up the msg queue\n");
    i = 0;
    while (i < number_users_logged_in) {
    if (users_logged_in[i].user_id == passed.id) {
    break;
    }
    i++;
    }
    users_logged_in[i].send_msg_id =
    msgget((key_t)users_logged_in[i].user_id, msgflg);

    msg_queue_id = users_logged_in[i].send_msg_id;
    if (msg_queue_id < 0) {
    fprintf(stderr, "problems\n");
    } else {
    fprintf(stderr, "no problems\n");
    }

    fprintf(stderr, "starting waiting on the queue\n");
    /* this is where is hangs here */
    while (msgrcv(msg_queue_id, (void*)&msgp, (size_t)msgp_max, 0, 0) > 0) {
    fprintf(stderr, "got msg\n");
    if (strncmp(msgp.mtext, "-", 1) == 0) {
    fprintf(stderr, "got breaking signal\n");
    break;
    }
    }
    msgctl(msg_queue_id, IPC_RMID, (struct msqid_ds *)NULL);

    Reid Guest

  2. #2

    Default Re: message queues and pthreads



    Reid Nichol wrote:
     
    ^^^^
    My man page for recv() specifies that the flags parameter
    (which you pass as NULL) is constructed by or-ing three
    flags, i.e.
    MSG_OOB process out-of-band data
    MSG_PEEK peek at incoming message
    MSG_WAITALL wait for full request or error

    presumably, none of these are defined in the header
    file as NULL.

    HTH
     

    --

    "It is impossible to make anything foolproof because fools are so
    ingenious" - A. Bloch

    Nick Guest

  3. #3

    Default Re: message queues and pthreads


    Same as mine. But, when I looked at online tutorials they did use NULL.
    I did try MSG_WAITALL but the result is the same behavior.

    Reid Guest

  4. #4

    Default Re: message queues and pthreads



    Reid Nichol wrote:
     
    >
    > Same as mine. But, when I looked at online tutorials they did use NULL.
    > I did try MSG_WAITALL but the result is the same behavior.
    > [/ref]

    OK ... the call which seems to hang is:

    ret = recv(csocket, (void*)r_c, sizeof(char), NULL);

    What's the r_c declared as?
    (you didn't post your declarations, BTW).

    As I interpret this, you are trying to read a single
    character from the socket. r_c should be a pointer
    to a character, or a pointer to a character within an
    array, but a pointer nontheless.

    If r_c is declared as just a char (not a char *)
    and uninitialized, casting
    it to a pointer may have the pointer pointing off into
    never-never land.

    --

    "It is impossible to make anything foolproof because fools are so
    ingenious" - A. Bloch

    Nick Guest

  5. #5

    Default Re: message queues and pthreads


    This works fine when there isn't any message queue in the code but
    freezes when there is one. It's like msgrcv is blocking the entire
    program instead of just the one thread.
     
    char r_c[2];

    The code compiles clean so I think that we can assume that they are of
    the right type, unless I'm mistake of course. I haven't done any
    serious programming in some time.

    Reid Guest

  6. #6

    Default Re: message queues and pthreads



    Reid Nichol wrote:
     
    >
    > This works fine when there isn't any message queue in the code but
    > freezes when there is one. It's like msgrcv is blocking the entire
    > program instead of just the one thread.
    >  
    >
    > char r_c[2];
    >
    > The code compiles clean so I think that we can assume that they are of
    > the right type, unless I'm mistake of course. I haven't done any
    > serious programming in some time.
    > [/ref]

    It may compile clean, but the cast to (void *) shut the compiler
    up about the mismatch.

    What you are saying to the compiler is that you want to take
    the >value< stored in r_c and use that >value< as a void
    pointer. What you want is an address at which to store the
    single character you are reading into it. I guess you were
    unlucky in that this did not cause a segmentation violation.

    Replace it with

    ret = recv(csocket, (void*)&r_c, sizeof(char), FLAGS);

    (either NULL or one the other flags) and see if that helps.


    --

    "It is impossible to make anything foolproof because fools are so
    ingenious" - A. Bloch

    Nick Guest

  7. #7

    Default Re: message queues and pthreads

    Switched to UNIX domain sockets. Works now.

    Reid Guest

  8. #8

    Default Re: message queues and pthreads

    Nick Landsberg wrote:
     
    >>
    >> This works fine when there isn't any message queue in the code but
    >> freezes when there is one. It's like msgrcv is blocking the entire
    >> program instead of just the one thread.
    >> 
    >>
    >> char r_c[2];
    >>
    >> The code compiles clean so I think that we can assume that they are of
    >> the right type, unless I'm mistake of course. I haven't done any
    >> serious programming in some time.[/ref]
    >
    > It may compile clean, but the cast to (void *) shut the compiler
    > up about the mismatch.
    >
    > What you are saying to the compiler is that you want to take
    > the >value< stored in r_c and use that >value< as a void
    > pointer. What you want is an address at which to store the
    > single character you are reading into it. I guess you were
    > unlucky in that this did not cause a segmentation violation.
    >
    > Replace it with
    >
    > ret = recv(csocket, (void*)&r_c, sizeof(char), FLAGS);[/ref]

    Your replacement is wrong. You pass the address of the array. But using
    the array name r_c will pass a pointer to the first element of the array.
    Maybe (if the application protocol requires it) the OP needs to adjust the
    size parameter too.

    ret = recv(csocket, r_c, sizeof r_c, FLAGS);

    Regards,
    Daniel
    Daniel Guest

Similar Threads

  1. Postfix and Queues
    By Vladimir in forum FreeBSD
    Replies: 2
    Last Post: March 25th, 05:24 PM
  2. Which lib for pthreads?
    By Jonathon in forum FreeBSD
    Replies: 10
    Last Post: March 7th, 03:45 PM
  3. Working with message queues
    By prashna in forum UNIX Programming
    Replies: 5
    Last Post: September 30th, 06:43 AM
  4. Message Queues
    By Tejus in forum UNIX Programming
    Replies: 2
    Last Post: August 14th, 10:00 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139