If I have two instances of Glib::IOChannel, they block until both written. What is the correct way to do this?

StackOverflow https://stackoverflow.com/questions/1043588

  •  20-08-2019
  •  | 
  •  

Question

I have modified the example found here to use two io channels. None of the callbacks seem to be called before I have written to both channels. After that they are called individually when writing to the fifos. Am I forgetting something?

  • Start the test program in one shell window.
  • Write echo "abc" > testfifo1 in second shell window. -> nothing happens.
  • Write echo "def" > testfifo2 in a third shell window. -> now I get "abc" and "def"
  • Write to one of the fifos. This is immediately served.

Edit: The solution, as hinted by Gormley below, was the lack of nonblock.

read_fd1 = open("testfifo1", O_RDONLY | O_NONBLOCK);
...
read_fd2 = open("testfifo2", O_RDONLY | O_NONBLOCK);

This change to the code below made it respond immediately.

The code:

#include <gtkmm/main.h>
#include <fcntl.h>
#include <iostream>

int read_fd1, read_fd2;
Glib::RefPtr<Glib::IOChannel> iochannel1, iochannel2;

// Usage: "echo "Hello" > testfifo<1|2>", quit with "Q"

bool MyCallback1(Glib::IOCondition io_condition)
{
    Glib::ustring buf;
    iochannel1->read_line(buf);
    std::cout << "io 1: " << buf;

    if (buf == "Q\n")
        Gtk::Main::quit();

    return true;
}

bool MyCallback2(Glib::IOCondition io_condition)
{
    Glib::ustring buf;
    iochannel2->read_line(buf);
    std::cout << "io 2: " << buf;

    if (buf == "Q\n")
        Gtk::Main::quit();

    return true;
}

int main(int argc, char *argv[])
{
    // the usual Gtk::Main object
    Gtk::Main app(argc, argv);

    if (access("testfifo1", F_OK) == -1)
    {
        if (mkfifo("testfifo1", 0666) != 0)
            return -1;
    }

    if (access("testfifo2", F_OK) == -1)
    {
        if (mkfifo("testfifo2", 0666) != 0)
            return -1;
    }

    read_fd1 = open("testfifo1", O_RDONLY);

    if (read_fd1 == -1)
        return -1;

    read_fd2 = open("testfifo2", O_RDONLY);

    if (read_fd2 == -1)
        return -1;

    Glib::signal_io().connect(sigc::ptr_fun(MyCallback1), read_fd1, Glib::IO_IN);
    Glib::signal_io().connect(sigc::ptr_fun(MyCallback2), read_fd2, Glib::IO_IN);

    iochannel1 = Glib::IOChannel::create_from_fd(read_fd1);
    iochannel2 = Glib::IOChannel::create_from_fd(read_fd2);

    app.run();

    if (unlink("testfifo1"))
        std::cerr << "error removing fifo 1" << std::endl;

    if (unlink("testfifo2"))
        std::cerr << "error removing fifo 2" << std::endl;

    return 0;
}
Was it helpful?

Solution

These two statements block the program from getting into the main loop until both fifos are open for write. fifos block until both sides are connected

iochannel1 = Glib::IOChannel::create_from_fd(read_fd1); iochannel2 = Glib::IOChannel::create_from_fd(read_fd2);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top