Repository: netty/netty
Issue: Assertion error in globalEventExecutor
Labels: defect

I am using Vertx 3.1 with Netty 4.0.31. Every once in a while, I got an assert on this line:

```
 protected final Runnable pollScheduledTask(long nanoTime) {
    assert this.inEventLoop();

    Queue scheduledTaskQueue = this.scheduledTaskQueue;
    ScheduledFutureTask scheduledTask = scheduledTaskQueue == null?null:(ScheduledFutureTask)scheduledTaskQueue.peek();
    if(scheduledTask == null) {
        return null;
    } else if(scheduledTask.deadlineNanos() <= nanoTime) {
        scheduledTaskQueue.remove();
        return scheduledTask;
    } else {
        return null;
    }
}
```

with the following stack trace:
"globalEventExecutor-1-1"@4,148 in group "main": RUNNING
pollScheduledTask():83, AbstractScheduledEventExecutor {io.netty.util.concurrent}
fetchFromScheduledTaskQueue():114, GlobalEventExecutor {io.netty.util.concurrent}
takeTask():99, GlobalEventExecutor {io.netty.util.concurrent}
run():230, GlobalEventExecutor$TaskRunner {io.netty.util.concurrent}
run():137, DefaultThreadFactory$DefaultRunnableDecorator {io.netty.util.concurrent}
run():745, Thread {java.lang} 

The thread that starts GlobalEventExecutor is
"main"@1 in group "main": RUNNING
<clinit>():37, GlobalEventExecutor {io.netty.util.concurrent}
<init>():35, MultithreadEventExecutorGroup {io.netty.util.concurrent}
<init>():49, MultithreadEventLoopGroup {io.netty.channel}
<init>():61, NioEventLoopGroup {io.netty.channel.nio}
<init>():52, NioEventLoopGroup {io.netty.channel.nio}
<init>():125, VertxImpl {io.vertx.core.impl}
<init>():114, VertxImpl {io.vertx.core.impl}
<init>():110, VertxImpl {io.vertx.core.impl}
vertx():34, VertxFactoryImpl {io.vertx.core.impl}
vertx():78, Vertx {io.vertx.core}


Issue comments:
Will check

@luengnat ok I think i know where the problem is... working on a fix now :+1: 

Fixed

Oddly I started encountering this issue while upgrading from jdk 8u60 to 8u65.  Not really sure why that would explain this.  I was just curious @luengnat do you happen to remember what JDK you were on when you were encountering this?    We've been on 4.0.26/4.0.27 for about 6 months or and I hadn't seen this issue once until we recently upgraded JDKs in our CI environment and it seems to happen occasionally.


Pull request review comments:

Patch that resolved the issue:
diff --git a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java
index 5f18ed8dda7..29d7ad12d36 100644
--- a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java
+++ b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java
@@ -218,8 +218,11 @@ public void execute(Runnable task) {
     private void startThread() {
         if (started.compareAndSet(false, true)) {
             Thread t = threadFactory.newThread(taskRunner);
-            t.start();
+            // Set the thread before starting it as otherwise inEventLoop() may return false and so produce
+            // an assert error.
+            // See https://github.com/netty/netty/issues/4357
             thread = t;
+            t.start();
         }
     }
 


Test patch: