src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/TimeoutEvent.java
author roland
Sat, 02 Dec 2017 13:50:04 +0100
changeset 48298 40b9faefb496
parent 47216 71c04702a3d5
permissions -rw-r--r--
8191950: assertion failed: no insertions allowed Summary: Check for dead loops before incremental inlining. Reviewed-by: thartmann
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     1
/*
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     4
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    10
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    15
 * accompanied this code).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    16
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    20
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    23
 * questions.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    24
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    25
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    26
package jdk.incubator.http;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    27
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    28
import java.time.Duration;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    29
import java.time.Instant;
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    30
import java.util.concurrent.atomic.AtomicLong;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    31
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    32
/**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    33
 * Timeout event notified by selector thread. Executes the given handler if
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    34
 * the timer not canceled first.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    35
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    36
 * Register with {@link HttpClientImpl#registerTimer(TimeoutEvent)}.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    37
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    38
 * Cancel with {@link HttpClientImpl#cancelTimer(TimeoutEvent)}.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    39
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    40
abstract class TimeoutEvent implements Comparable<TimeoutEvent> {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    41
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    42
    private static final AtomicLong COUNTER = new AtomicLong();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    43
    // we use id in compareTo to make compareTo consistent with equals
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    44
    // see TimeoutEvent::compareTo below;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    45
    private final long id = COUNTER.incrementAndGet();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    46
    private final Instant deadline;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    47
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    48
    TimeoutEvent(Duration duration) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    49
        deadline = Instant.now().plus(duration);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    50
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    51
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    52
    public abstract void handle();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    53
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    54
    public Instant deadline() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    55
        return deadline;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    56
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    57
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    58
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    59
    public int compareTo(TimeoutEvent other) {
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    60
        if (other == this) return 0;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    61
        // if two events have the same deadline, but are not equals, then the
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    62
        // smaller is the one that was created before (has the smaller id).
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    63
        // This is arbitrary and we don't really care which is smaller or
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    64
        // greater, but we need a total order, so two events with the
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    65
        // same deadline cannot compare == 0 if they are not equals.
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    66
        final int compareDeadline = this.deadline.compareTo(other.deadline);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    67
        if (compareDeadline == 0 && !this.equals(other)) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    68
            long diff = this.id - other.id; // should take care of wrap around
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    69
            if (diff < 0) return -1;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    70
            else if (diff > 0) return 1;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    71
            else assert false : "Different events with same id and deadline";
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    72
        }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    73
        return compareDeadline;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    74
    }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    75
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    76
    @Override
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    77
    public String toString() {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 42460
diff changeset
    78
        return "TimeoutEvent[id=" + id + ", deadline=" + deadline + "]";
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    79
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    80
}