1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.util.concurrent;
17
18 import io.netty5.util.internal.logging.InternalLogger;
19
20 import java.util.Arrays;
21 import java.util.EventListener;
22
23 final class DefaultFutureListeners {
24 private Object[] listeners;
25 private int size;
26
27 DefaultFutureListeners() {
28 listeners = new Object[4];
29 }
30
31 public void add(Object listener, Object context) {
32 Object[] listeners = this.listeners;
33 int index = size << 1;
34 if (index == listeners.length) {
35 this.listeners = listeners = Arrays.copyOf(listeners, listeners.length << 1);
36 }
37 listeners[index] = listener;
38 listeners[index + 1] = context;
39 size++;
40 }
41
42 public void remove(EventListener listener) {
43 final Object[] listeners = this.listeners;
44 for (int i = 0, len = listeners.length; i < len; i += 2) {
45 Object candidateListener = listeners[i];
46 if (candidateListener == listener) {
47 int listenersToMove = len - i - 2;
48 if (listenersToMove > 0) {
49 System.arraycopy(listeners, i + 2, listeners, i, listenersToMove);
50 }
51 listeners[len - 2] = null;
52 listeners[len - 1] = null;
53 size--;
54 return;
55 }
56 }
57 }
58
59 @SuppressWarnings("unchecked")
60 public <V> void notifyListeners(DefaultPromise<V> promise, InternalLogger logger) {
61 int size = this.size;
62 Object[] listeners = this.listeners;
63 for (int i = 0, len = size << 1; i < len; i += 2) {
64 Object listener = listeners[i];
65 Object context = listeners[i + 1];
66 try {
67
68
69
70
71
72 if (context != null) {
73 FutureContextListener<Object, V> fcl = (FutureContextListener<Object, V>) listener;
74 fcl.operationComplete(context == DefaultPromise.NULL_CONTEXT ? null : context, promise);
75 } else if (listener instanceof FutureListener) {
76 FutureListener<V> fl = (FutureListener<V>) listener;
77 fl.operationComplete(promise);
78 } else if (listener != null) {
79 logger.warn("Unknown future listener type: {} of type {}", listener, listener.getClass());
80 } else {
81 break;
82 }
83 } catch (Throwable t) {
84 if (logger.isWarnEnabled()) {
85 String className = listener.getClass().getName();
86 logger.warn("An exception was thrown by " + className + ".operationComplete()", t);
87 }
88 }
89 }
90 }
91 }