Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

event_loop_thread can't start after fork #56

Closed
shgxwxl opened this issue Jul 13, 2017 · 1 comment
Closed

event_loop_thread can't start after fork #56

shgxwxl opened this issue Jul 13, 2017 · 1 comment

Comments

@shgxwxl
Copy link
Contributor

shgxwxl commented Jul 13, 2017

We create EventLoopThread and initialize it in father process, but we use it in child process.
If we have only one child process , everything goes well.

But if we have multi child processes, something goes wrong.
Because EventLoop::watcher_ is created and initialized in father process, all children processes inherited father's pipe. When we use the pipe to do a notification in one child process, the notification may be received by another child process randomly.

if it's message had readed by other process
we marked watcher had been notified_ and never notify it again

    if (!notified_.load()) {
        DLOG_TRACE << "call watcher_->Nofity() notified_.store(true)";

        // We must set notified_ to true before calling `watcher_->Nodify()`
        // otherwise there is a change that:
        //  1. We called watcher_- > Nodify() on thread1
        //  2. On thread2 we watched this event, so wakeup the CPU changed to run this EventLoop on thread2 and executed all the pending task
        //  3. Then the CPU changed to run on thread1 and set notified_ to true
        //  4. Then, some thread except thread2 call this QueueInLoop to push a task into the queue, and find notified_ is true, so there is no change to wakeup thread2 to execute this task
        notified_.store(true);

        // Sometimes one thread invoke EventLoop::QueueInLoop(...), but anther
        // thread is invoking EventLoop::Stop() to stop this loop. At this moment
        // this loop maybe is stopping and the watcher_ object maybe has been
        // released already.
        if (watcher_) {
            watcher_->Notify();
        } else {
            DLOG_TRACE << "status=" << StatusToString();
            assert(!IsRunning());
        }
    } else {
         DLOG_TRACE << "No need to call watcher_->Nofity()";
    }
zieckey added a commit that referenced this issue Jul 13, 2017
@zieckey
Copy link
Collaborator

zieckey commented Jul 14, 2017

Fixed 9fc8601

@zieckey zieckey closed this as completed Jul 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants