2
gcc 4.7.2
c89
APR 1.4

Hello,

I am using APR thread pools, event loop (polling), and message queue (msgget, msgsnd, msgrcv).

Currently, I am just testing that if I press ctrl-c. It will set the while to false. So the message will be sent in my signal handler to be received in my while loop.

However, the msgrcv seems to block in my event loop. So I can't get any other events from my library. In my event loop I am checking if a message has been recevied. However, I think it blocks waiting for a message. This will cause my loop to stop looping and I won't be able to capture any event from my library.

This is the first time I have used message queues.

Here is my code, I am only copied the relevent parts so I have removed all error checking to keep it short.

Currently I am just testing that my event loop can receive a message from the queue, so it can stop the loop.

Many thanks for any suggestions,

#define MSG_KEY 0001L
static int msg_id = 0;
static volatile apr_status_t is_looping = FALSE;

/* Wait for these message commands */
typedef enum tag_msg_cmd {END_LOOP, START_LOOP} msg_cmd_e;

/* message queue data */
typedef struct tag_msg_data msg_data_t;
struct tag_msg_data {
    long mtype;
    msg_cmd_e msg_cmd;
};

int main(void)
{
    /* Create message queue */
    msg_id = msgget(MSG_KEY, 0666 | IPC_CREAT);

    /* Create thread pool */
    has_error = apr_thread_pool_create(&thd_pool,
                                       init_threads,
                                       max_threads,
                                       mem_pool_app);

   /* Start event loop */
   LOG_CHECK(apr_thread_pool_schedule(thd_pool,
                                       (apr_thread_start_t)event_loop,
                                       NULL,
                                       0,
                                       NULL) == APR_SUCCESS, "Failed to schedule event loop");

    /* Pause until ctrl-c */
    pause();

    /* Destroy all memory pools and threading pools */
}

/* Poll for incoming events */
static apr_status_t event_loop(void)
{
    msg_data_t msg_data;
    int evt_id = 0;
    int msg_id = 0;

    /* Connect to the message queue */
    msg_id = msgget(MSG_KEY, 0644);
    assert(msg_id != -1 && "Failed to connect to the message queue");
    LOG_DEBUG("Connected to message queue with msg ID [ %d ]", msg_id);

    while(is_looping) {
        /* Under development - Process incoming event from shared library */
        /* evt_id = sr_waitevt(timeout_ms); */
        /* process_event(evt_id); */

        LOG_DEBUG("Looping....");

        /* Should not be blocking here, as I need to receive other events */
        msgrcv(msg_id, &msg_data, (sizeof msg_data) - (sizeof(long)), 2, 0);
        LOG_DEBUG("Waiting...");
        if(msg_data.msg_cmd == END_LOOP) {
            LOG_DEBUG("END_LOOP event queue message has been received");
            break;
        }
        sleep(1);
    }

    return 1;
}

/* Signal handler will terminated application on ctrl-c */
static void signal_handler(int sig)
{
    msg_data_t msg_data = {2,  END_LOOP};
    int rc = 0;

    rc = msgsnd(msg_id,
                &msg_data,
                (sizeof msg_data) - (sizeof(long)),
                IPC_NOWAIT);

    assert(rc == 0 && "Failed to send data to the message queue");
}

1 Answer 1

1

Set the flag parameter on msgrcv (the 5th parm) to IPC_NOWAIT. This makes the queue receive non-blocking.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I did actually try that and it didn't work. I think I was playing around too much with the code. However, yes its working now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.