8034801: AIX: (ch) Fix synchronization issue in AixPollPort.java
authorsimonis
Fri, 14 Feb 2014 11:23:58 +0100
changeset 22972 a956e9de07ed
parent 22971 0664d4b8f97f
child 22973 616ad2891b71
8034801: AIX: (ch) Fix synchronization issue in AixPollPort.java Reviewed-by: alanb
jdk/src/aix/classes/sun/nio/ch/AixPollPort.java
--- a/jdk/src/aix/classes/sun/nio/ch/AixPollPort.java	Thu Feb 13 11:15:56 2014 +0800
+++ b/jdk/src/aix/classes/sun/nio/ch/AixPollPort.java	Fri Feb 14 11:23:58 2014 +0100
@@ -107,6 +107,7 @@
     private final ArrayBlockingQueue<Event> queue;
     private final Event NEED_TO_POLL = new Event(null, 0);
     private final Event EXECUTE_TASK_OR_SHUTDOWN = new Event(null, 0);
+    private final Event CONTINUE_AFTER_CTL_EVENT = new Event(null, 0);
 
     // encapsulates a pollset control event for a file descriptor
     static class ControlEvent {
@@ -342,7 +343,11 @@
 
                             // To emulate one shot semantic we need to remove
                             // the file descriptor here.
-                            pollsetCtl(pollset, PS_DELETE, fd, 0);
+                            if (fd != sp[0] && fd != ctlSp[0]) {
+                                synchronized (controlQueue) {
+                                    pollsetCtl(pollset, PS_DELETE, fd, 0);
+                                }
+                            }
 
                             // wakeup
                             if (fd == sp[0]) {
@@ -351,10 +356,6 @@
                                     drain1(sp[0]);
                                 }
 
-                                // This is the only file descriptor without
-                                // one shot semantic => register it again.
-                                pollsetCtl(pollset, PS_ADD, sp[0], Net.POLLIN);
-
                                 // queue special event if there are more events
                                 // to handle.
                                 if (n > 0) {
@@ -368,12 +369,12 @@
                             if (fd == ctlSp[0]) {
                                 synchronized (controlQueue) {
                                     drain1(ctlSp[0]);
-                                    // This file descriptor does not have
-                                    // one shot semantic => register it again.
-                                    pollsetCtl(pollset, PS_ADD, ctlSp[0], Net.POLLIN);
                                     processControlQueue();
                                 }
-                                continue;
+                                if (n > 0) {
+                                    continue;
+                                }
+                                return CONTINUE_AFTER_CTL_EVENT;
                             }
 
                             PollableChannel channel = fdToChannel.get(fd);
@@ -431,6 +432,11 @@
                         continue;
                     }
 
+                    // contine after we processed a control event
+                    if (ev == CONTINUE_AFTER_CTL_EVENT) {
+                        continue;
+                    }
+
                     // handle wakeup to execute task or shutdown
                     if (ev == EXECUTE_TASK_OR_SHUTDOWN) {
                         Runnable task = pollTask();