jdk/test/java/nio/channels/Selector/LotsOfCancels.java
author dfuchs
Wed, 07 Nov 2012 13:24:39 +0100
changeset 14415 7a31b0e0cfaf
parent 5506 202f599c92aa
permissions -rw-r--r--
6720349: (ch) Channels tests depending on hosts inside Sun Summary: This changeset make the nio tests start small TCP or UDP servers from within the tests, instead of relying on external services. Reviewed-by: alanb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4183
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     1
/*
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     2
 * Copyright 2009 Google Inc.  All Rights Reserved.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     4
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     7
 * published by the Free Software Foundation.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     8
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    13
 * accompanied this code).
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    14
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    18
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4183
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4183
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4183
diff changeset
    21
 * questions.
4183
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    22
 */
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    23
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    24
import java.net.InetSocketAddress;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    25
import java.net.SocketAddress;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    26
import java.nio.channels.SelectionKey;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    27
import java.nio.channels.Selector;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    28
import java.nio.channels.ServerSocketChannel;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    29
import java.nio.channels.SocketChannel;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    30
import java.util.ArrayList;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    31
import java.util.Iterator;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    32
import java.util.List;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    33
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    34
/**
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    35
 * Reproduces O(N^2) behavior of JDK6/7 select() call. This happens when
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    36
 * a selector has many unprocessed updates to its interest set (e.g. adding
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    37
 * OP_READ on a bunch of newly accepted sockets). The O(N^2) is triggered
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    38
 * by cancelling a number of selection keys (or just closing a few sockets).
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    39
 * In this case, select() will first go through the list of cancelled keys
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    40
 * and try to deregister them. That deregistration is O(N^2) over the list
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    41
 * of unprocessed updates to the interest set.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    42
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    43
 * <p> This O(N^2) behavior is a BUG in JVM and should be fixed.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    44
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    45
 * <p> The test first creates initCount connections, and adds them
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    46
 * to the server epoll set. It then creates massCount connections,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    47
 * registers interest (causing updateList to be populated with massCount*2
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    48
 * elements), but does not add them to epoll set (that would've cleared
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    49
 * updateList). The test then closes initCount connections, thus populating
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    50
 * deregistration queue. The subsequent call to selectNow() will first process
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    51
 * deregistration queue, performing O(N^2) over updateList size,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    52
 * equal to massCount * 2.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    53
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    54
 * <p> Note that connect rate is artificially slowed down to compensate
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    55
 * for what I believe is a Linux bug, where too high of a connection rate
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    56
 * ends up in SYN's being dropped and then slow retransmits.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    57
 *
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    58
 * @author Igor Chernyshev
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    59
 */
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    60
public class LotsOfCancels {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    61
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    62
    static long testStartTime;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    63
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    64
    public static void main(String[] args) throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    65
        // the final select should run in less than 1000ms.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    66
        runTest(500, 2700, 1000);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    67
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    68
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    69
    static void log(String msg) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    70
        System.out.println(getLogPrefix() + msg);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    71
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    72
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    73
    static String getLogPrefix() {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    74
        return durationMillis(testStartTime) + ": ";
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    75
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    76
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    77
    /**
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    78
     * Returns the elapsed time since startNanos, in milliseconds.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    79
     * @param startNanos the start time; this must be a value returned
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    80
     * by {@link System.nanoTime}
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    81
     */
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    82
    static long durationMillis(long startNanos) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    83
        return (System.nanoTime() - startNanos) / (1000L * 1000L);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    84
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    85
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    86
    static void runTest(int initCount, int massCount, int maxSelectTime)
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    87
            throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    88
        testStartTime = System.nanoTime();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    89
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    90
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 7359);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    91
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    92
        // Create server channel, add it to selector and run epoll_ctl.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    93
        log("Setting up server");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    94
        Selector serverSelector = Selector.open();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    95
        ServerSocketChannel server = ServerSocketChannel.open();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    96
        server.configureBlocking(false);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    97
        server.socket().bind(address, 5000);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    98
        server.register(serverSelector, SelectionKey.OP_ACCEPT);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
    99
        serverSelector.selectNow();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   100
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   101
        log("Setting up client");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   102
        ClientThread client = new ClientThread(address);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   103
        client.start();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   104
        Thread.sleep(100);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   105
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   106
        // Set up initial set of client sockets.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   107
        log("Starting initial client connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   108
        client.connectClients(initCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   109
        Thread.sleep(500);  // Wait for client connections to arrive
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   110
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   111
        // Accept all initial client sockets, add to selector and run
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   112
        // epoll_ctl.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   113
        log("Accepting initial connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   114
        List<SocketChannel> serverChannels1 =
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   115
            acceptAndAddAll(serverSelector, server, initCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   116
        if (serverChannels1.size() != initCount) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   117
            throw new Exception("Accepted " + serverChannels1.size() +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   118
                                " instead of " + initCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   119
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   120
        serverSelector.selectNow();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   121
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   122
        // Set up mass set of client sockets.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   123
        log("Requesting mass client connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   124
        client.connectClients(massCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   125
        Thread.sleep(500);  // Wait for client connections to arrive
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   126
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   127
        // Accept all mass client sockets, add to selector and do NOT
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   128
        // run epoll_ctl.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   129
        log("Accepting mass connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   130
        List<SocketChannel> serverChannels2 =
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   131
            acceptAndAddAll(serverSelector, server, massCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   132
        if (serverChannels2.size() != massCount) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   133
            throw new Exception("Accepted " + serverChannels2.size() +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   134
                                " instead of " + massCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   135
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   136
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   137
        // Close initial set of sockets.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   138
        log("Closing initial connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   139
        closeAll(serverChannels1);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   140
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   141
        // Now get the timing of select() call.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   142
        log("Running the final select call");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   143
        long startTime = System.nanoTime();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   144
        serverSelector.selectNow();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   145
        long duration = durationMillis(startTime);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   146
        log("Init count = " + initCount +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   147
            ", mass count = " + massCount +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   148
            ", duration = " + duration + "ms");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   149
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   150
        if (duration > maxSelectTime) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   151
            System.out.println
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   152
                ("\n\n\n\n\nFAILURE: The final selectNow() took " +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   153
                 duration + "ms " +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   154
                 "- seems like O(N^2) bug is still here\n\n");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   155
            System.exit(1);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   156
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   157
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   158
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   159
    static List<SocketChannel> acceptAndAddAll(Selector selector,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   160
                                               ServerSocketChannel server,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   161
                                               int expected)
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   162
            throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   163
        int retryCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   164
        int acceptCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   165
        List<SocketChannel> channels = new ArrayList<SocketChannel>();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   166
        while (channels.size() < expected) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   167
            SocketChannel channel = server.accept();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   168
            if (channel == null) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   169
                log("accept() returned null " +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   170
                    "after accepting " + acceptCount + " more connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   171
                acceptCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   172
                if (retryCount < 10) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   173
                    // See if more new sockets got stacked behind.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   174
                    retryCount++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   175
                    Thread.sleep(500);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   176
                    continue;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   177
                }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   178
                break;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   179
            }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   180
            retryCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   181
            acceptCount++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   182
            channel.configureBlocking(false);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   183
            channel.register(selector, SelectionKey.OP_READ);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   184
            channels.add(channel);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   185
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   186
        // Cause an additional updateList entry per channel.
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   187
        for (SocketChannel channel : channels) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   188
            channel.register(selector, SelectionKey.OP_WRITE);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   189
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   190
        return channels;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   191
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   192
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   193
    static void closeAll(List<SocketChannel> channels)
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   194
            throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   195
        for (SocketChannel channel : channels) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   196
            channel.close();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   197
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   198
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   199
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   200
    static class ClientThread extends Thread {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   201
        private final SocketAddress address;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   202
        private final Selector selector;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   203
        private int connectionsNeeded;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   204
        private int totalCreated;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   205
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   206
        ClientThread(SocketAddress address) throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   207
            this.address = address;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   208
            selector = Selector.open();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   209
            setDaemon(true);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   210
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   211
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   212
        void connectClients(int count) throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   213
            synchronized (this) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   214
                connectionsNeeded += count;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   215
            }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   216
            selector.wakeup();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   217
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   218
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   219
        @Override
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   220
        public void run() {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   221
            try {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   222
                handleClients();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   223
            } catch (Throwable e) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   224
                e.printStackTrace();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   225
                System.exit(1);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   226
            }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   227
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   228
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   229
        private void handleClients() throws Exception {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   230
            int selectCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   231
            while (true) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   232
                int createdCount = 0;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   233
                synchronized (this) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   234
                    if (connectionsNeeded > 0) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   235
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   236
                        while (connectionsNeeded > 0 && createdCount < 20) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   237
                            connectionsNeeded--;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   238
                            createdCount++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   239
                            totalCreated++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   240
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   241
                            SocketChannel channel = SocketChannel.open();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   242
                            channel.configureBlocking(false);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   243
                            channel.connect(address);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   244
                            if (!channel.finishConnect()) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   245
                                channel.register(selector,
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   246
                                                 SelectionKey.OP_CONNECT);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   247
                            }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   248
                        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   249
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   250
                        log("Started total of " +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   251
                            totalCreated + " client connections");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   252
                        Thread.sleep(200);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   253
                    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   254
                }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   255
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   256
                if (createdCount > 0) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   257
                    selector.selectNow();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   258
                } else {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   259
                    selectCount++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   260
                    long startTime = System.nanoTime();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   261
                    selector.select();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   262
                    long duration = durationMillis(startTime);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   263
                    log("Exited clientSelector.select(), loop #"
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   264
                        + selectCount + ", duration = " + duration + "ms");
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   265
                }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   266
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   267
                int keyCount = -1;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   268
                Iterator<SelectionKey> keys =
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   269
                    selector.selectedKeys().iterator();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   270
                while (keys.hasNext()) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   271
                    SelectionKey key = keys.next();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   272
                    synchronized (key) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   273
                        keyCount++;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   274
                        keys.remove();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   275
                        if (!key.isValid()) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   276
                            log("Ignoring client key #" + keyCount);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   277
                            continue;
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   278
                        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   279
                        int readyOps = key.readyOps();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   280
                        if (readyOps == SelectionKey.OP_CONNECT) {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   281
                            key.interestOps(0);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   282
                            ((SocketChannel) key.channel()).finishConnect();
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   283
                        } else {
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   284
                            log("readyOps() on client key #" + keyCount +
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   285
                                " returned " + readyOps);
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   286
                        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   287
                    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   288
                }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   289
            }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   290
        }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   291
    }
0e342cecb3a9 6897993: (se) Close or cancel performance issue when number of pending updates is high (lnx)
martin
parents:
diff changeset
   292
}