ae2677b0e2b5d363fe7c578dde448579907cfe2e
[yangtools.git] / common / concepts / src / main / java / org / opendaylight / yangtools / concepts / AbstractRegistration.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.concepts;
9
10 import com.google.common.base.MoreObjects;
11 import com.google.common.base.MoreObjects.ToStringHelper;
12 import java.lang.invoke.MethodHandles;
13 import java.lang.invoke.VarHandle;
14
15 /**
16  * Utility registration handle. It is a convenience for register-style method which can return an AutoCloseable realized
17  * by a subclass of this class. Invoking the close() method triggers unregistration of the state the method installed.
18  */
19 public abstract class AbstractRegistration implements Registration {
20     private static final VarHandle CLOSED;
21
22     // All access needs to go through this handle
23     @SuppressWarnings("unused")
24     private volatile byte closed;
25
26     static {
27         try {
28             CLOSED = MethodHandles.lookup().findVarHandle(AbstractRegistration.class, "closed", byte.class);
29         } catch (ReflectiveOperationException e) {
30             throw new ExceptionInInitializerError(e);
31         }
32     }
33
34     /**
35      * Remove the state referenced by this registration. This method is guaranteed to be called at most once.
36      * Referenced state must be retained until this method is invoked.
37      */
38     protected abstract void removeRegistration();
39
40     /**
41      * Query the state of this registration. Returns true if it was closed. Equivalent of {@code !notClosed()}.
42      *
43      * @return true if the registration was closed, false otherwise.
44      */
45     public final boolean isClosed() {
46         return (byte) CLOSED.getAcquire(this) != 0;
47     }
48
49     /**
50      * Query the state of this registration. Returns false if it was closed. Equivalent of {@code !isClosed()}.
51      *
52      * @return false if the registration was closed, true otherwise.
53      */
54     public final boolean notClosed() {
55         return (byte) CLOSED.getAcquire(this) == 0;
56     }
57
58     @Override
59     public final void close() {
60         // We want full setVolatile() memory semantics here, as all state before calling this method
61         // needs to be visible
62         if (CLOSED.compareAndSet(this, (byte) 0, (byte) 1)) {
63             removeRegistration();
64         }
65     }
66
67     @Override
68     public final String toString() {
69         return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
70     }
71
72     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
73         return toStringHelper.add("closed", isClosed());
74     }
75 }