0

I need to implement a timer that checks for conditions every 35 seconds. My program is using IPC schemes to communicate information back and forth between client and server processes. The problem is that I am running msgrcv() function in a loop, which pauses the loop until it finds a message, which is no good because I need the timer to always be checking if a client has stopped sending messages. (if it only checks when it receives a message, this will be useless...)

The problem may seem unclear, but the basics of what I need is a way to implement a Watchdog timer that will check a condition every 35 seconds.

I currently have this code:

time_t start = time(NULL);

//Enter main processing loop
while(running)
{
    size_t size = sizeof(StatusMessage) - sizeof(long);

    if(msgrcv(messageID, &statusMessage, size, 0, 0) != -1)
    {
        printf("(SERVER) Message Data (ID #%ld)  =  %d  :  %s\n", statusMessage.machineID, statusMessage.status_code, statusMessage.status);

        masterList->msgQueueID = messageID;
        int numDCs = ++masterList->numberOfDCs;

        masterList->dc[numDCs].dcProcessID = (pid_t) statusMessage.machineID;
        masterList->dc[numDCs].lastTimeHeardFrom = 1000;

        printf("%d\n", masterList->numberOfDCs);
    }

    printf("%.2f\n", (double) (time(NULL) - start));
}

The only problem is as I stated before, the code to check how much time has passed, won't be reached if there is no message to come in, as the msgrcv function will hold the process.

I hope I am making sense, and that someone will be able to assist me in my problem.

Kyle Jensen
  • 419
  • 9
  • 27
  • It isn't clear on who is posting the messages into the queue. Also, why not arm a timer and check to see if there is a message in the queue, without blocking on it? – Ravi Mar 17 '16 at 00:13
  • Another simpler approach is to sleep for 35 seconds before invoking msgrecv() without blocking on it in the while loop. – Ravi Mar 17 '16 at 00:19
  • That makes sense, my only problem was that if I do that and I have 10 clients talking to the server, its going to take 35 seconds to process each request – Kyle Jensen Mar 17 '16 at 00:21
  • Is there a way I can check the size of the message queue? That might actually work for what I need to do – Kyle Jensen Mar 17 '16 at 00:21
  • Pls post the data type used for your message queue i.e., the declaration part. – Ravi Mar 17 '16 at 00:39

1 Answers1

1

You may want to try the msgctl(msqid, IPC_STAT, struct msqid_ds *msgqdsbuf); If the call is successful, then the current number of messages can be found using msgdsbuf->msg_qnum. The caller needed read permissions, which I think you may have in here.

Ravi
  • 88
  • 5
  • So if that call is not successful then it means there are no messages? Or do I just compare the value of the msg_qnum with 0? – Kyle Jensen Mar 17 '16 at 01:07
  • Initially, you may want to clear off msgdsbuf to zeros. On success, IPC_STAT, IPC_SET, and IPC_RMID return 0. On error, -1 is returned with errno indicating the error. So, you would check for the msgdsbuf->msg_qnum only when the return status is 0, of course. – Ravi Mar 17 '16 at 01:15
  • What exactly do I pass in as the msgdsbuf value? – Kyle Jensen Mar 17 '16 at 01:21
  • Look at this example posted here. https://www.ibm.com/support/knowledgecenter/#!/ssw_i5_54/apis/ipcmsgct.htm – Ravi Mar 17 '16 at 01:27
  • I am getting a segmentation fault. Could you post a code example? – Kyle Jensen Mar 17 '16 at 02:39
  • Consult man pages for detaled info. Ignored error detection. `int sndcnt = 2; int rcvcnt = 1; struct msqid_ds ctlbuf = { 0, }; // Buffer for IPC_STAT for (int i = sndcnt; i > 0; i--) msgsnd(msgqid, sndbuf, (sizeof(sndbuf)/sizeof(sndbuf[0])), IPC_NOWAIT); printf("# of test messages = %d\n", sndcnt); for (int i = rcvcnt; i > 0; i--) msgrcv(msgqid, rcvbuf, sizeof(rcvbuf), 0, IPC_NOWAIT); msgctl(msgqid, IPC_STAT, &ctlbuf); printf("msg_qnum = %ld (send count[%d] - receive count[%d])\n", ctlbuf.msg_qnum, sndcnt, rcvcnt); msgctl(msgqid, IPC_RMID, (struct msqid_ds *)NULL);` – Ravi Mar 18 '16 at 04:31
  • @kyle-jensen, couldn't format the code in the comment posted above. – Ravi Mar 18 '16 at 04:32