nextmethod.threading.WaitHandle.java Source code

Java tutorial

Introduction

Here is the source code for nextmethod.threading.WaitHandle.java

Source

/*
 * Copyright 2014 Jordan S. Jones <jordansjones@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nextmethod.threading;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;

import com.google.common.collect.ImmutableSet;
import nextmethod.annotations.Internal;
import nextmethod.base.IDisposable;
import nextmethod.base.NotImplementedException;
import nextmethod.base.ObjectDisposedException;

// TODO
abstract class WaitHandle implements IDisposable {

    static final WaitHandle DefaultHandle = new WaitHandle(false) {

    };

    @Internal
    static final int WaitTimeout = 258;

    @Internal
    protected volatile AtomicBoolean disposed = new AtomicBoolean(false);

    @Internal
    protected volatile AtomicBoolean state;

    private volatile Queue<Thread> waiters = new ConcurrentLinkedQueue<>();

    protected WaitHandle(final boolean initialState) {
        this.state = new AtomicBoolean(initialState);
    }

    protected boolean isSet() {
        return state.get();
    }

    public boolean reset() {
        synchronized (this) {
            checkDisposed();
            return state.compareAndSet(true, false);
        }
    }

    public boolean set() {
        final ImmutableSet<Thread> threads;
        synchronized (this) {
            checkDisposed();

            if (!state.compareAndSet(false, true)) {
                return false;
            }
            threads = ImmutableSet.copyOf(waiters);
            waiters.clear();
        }
        threads.forEach(LockSupport::unpark);
        return true;
    }

    @Override
    public void close() {
        close(true);
    }

    protected void close(boolean explicitClose) {
        if (!disposed.get()) {
            synchronized (this) {
                if (disposed.get()) {
                    return;
                }

                disposed.set(true);
            }
        }
    }

    @Internal
    protected void checkDisposed() {
        if (disposed.get()) {
            throw new ObjectDisposedException(getClass().getName());
        }
    }

    private boolean await() {
        final Thread current = Thread.currentThread();
        waiters.add(current);
        LockSupport.park();
        return isSet();
    }

    private boolean await(final long amount, final TimeUnit timeUnit) {
        if (amount == 0) {
            return set();
        }

        final Thread current = Thread.currentThread();
        waiters.add(current);
        LockSupport.parkUntil(timeUnit.toMillis(amount));
        return isSet();
    }

    public static boolean awaitOne() {
        return DefaultHandle.await();
    }

    public static boolean awaitOne(final long millisecondsToWait) {
        return awaitOne(millisecondsToWait, TimeUnit.MILLISECONDS);
    }

    public static boolean awaitOne(final long amount, final TimeUnit timeUnit) {
        return DefaultHandle.await(amount, timeUnit);
    }

    public static boolean awaitAll(final EventWaitHandle... waitHandles) {
        throw new NotImplementedException();
    }

    public static boolean awaitAll(final long millisecondsToWait, final WaitHandle... waitHandles) {
        throw new NotImplementedException();
    }

    public static boolean awaitAll(final long amount, final TimeUnit timeUnit, final WaitHandle... waithandles) {
        throw new NotImplementedException();
    }

    public static int awaitAny(final WaitHandle... waitHandles) {
        throw new NotImplementedException();
    }

    public static int awaitAny(final long millisecondsToWait, final WaitHandle... waitHandles) {
        return awaitAny(millisecondsToWait, TimeUnit.MILLISECONDS, waitHandles);
    }

    public static int awaitAny(final long millisecondsToWait, final TimeUnit timeUnit,
            final WaitHandle... waitHandles) {
        //      try {
        //         for (WaitHandle waitHandle : waitHandles) {
        //            waitHandle.await(millisecondsToWait, timeUnit);
        //         }
        //      }
        //      catch (InterruptedException e) {
        //
        //      }
        throw new NotImplementedException();
    }

    //   private static int awaitAny(final long timeout, final TimeUnit timeUnit, final ManualResetEvent... handles) {
    //      final long waitTime = timeUnit.toMillis(timeout);
    //      for (int i = 0; i < handles.length; i++) {
    //         if (handles[i].await(timeout, timeUnit)) {
    //            return i;
    //         }
    //      }
    //      return WaitHandle.WaitTimeout;
    //   }

    //   public boolean await() {
    //      return await(CancellationToken.none());
    //   }
    //
    //   public boolean await(final long timeout, @Nonnull final TimeUnit unit) {
    //      return await(timeout, unit, CancellationToken.none());
    //   }
    //
    //   public boolean await(@Nonnull final CancellationToken cancellationToken) {
    //      return await(Long.MAX_VALUE, TimeUnit.DAYS, cancellationToken);
    //   }
    //
    //   public boolean await(final long timeout, @Nonnull final TimeUnit unit, @Nonnull final CancellationToken cancellationToken) {
    //      checkArgument(timeout > -1);
    //
    //      throwIfClosed();
    //      if (!isSet()) {
    //
    //         final SpinWait spinWait = new SpinWait();
    //
    //         while (!isSet()) {
    //            cancellationToken.throwIfCancellationRequested();
    //
    //            if (spinWait.count() < spinCount) {
    //               spinWait.spinOnce();
    //               continue;
    //            }
    //
    //            break;
    //         }
    //
    //         if (isSet()) {
    //            return true;
    //         }
    //
    //         final EventWaitHandle handle = getWaitHandle();
    //
    //         if (cancellationToken.canBeCanceled()) {
    //            final int result = WaitHandle.awaitAny(timeout, unit, handle, cancellationToken.getWaitHandle());
    //            if (result == 1) {
    //               throw new OperationCanceledException(cancellationToken);
    //            }
    //            if (result == WaitHandle.WaitTimeout) {
    //               return false;
    //            }
    //         }
    //         else {
    //            if (!handle.awaitOne(timeout, unit)) {
    //               return false;
    //            }
    //         }
    //      }
    //      return true;
    //   }
    //
    //   public boolean awaitOne() {
    //      return awaitOne(Integer.MAX_VALUE, TimeUnit.DAYS);
    //   }
    //
    //   public boolean awaitOne(final long amount, final TimeUnit timeUnit) {
    //      throwIfClosed();
    //      boolean interrupted = false;
    //      try {
    //         timeUnit.sleep(amount);
    //      }
    //      catch (InterruptedException e) {
    //         interrupted = true;
    //      }
    //      finally {
    //         if (interrupted) {
    //            Thread.currentThread().interrupt();
    //         }
    //      }
    //      return isSet();
    //   }
}