001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.util.concurrent; 006 007import edu.wpi.first.util.WPIUtilJNI; 008 009/** 010 * A semaphore for synchronization. 011 * 012 * <p>Semaphores keep an internal counter. Releasing the semaphore increases the count. A semaphore 013 * with a non-zero count is considered signaled. When a waiter wakes up it atomically decrements the 014 * count by 1. This is generally useful in a single-supplier, multiple-consumer scenario. 015 */ 016public final class Semaphore implements AutoCloseable { 017 /** 018 * Constructor. 019 * 020 * @param initialCount initial value for the semaphore's internal counter 021 * @param maximumCount maximum value for the semaphore's internal counter 022 */ 023 public Semaphore(int initialCount, int maximumCount) { 024 m_handle = WPIUtilJNI.createSemaphore(initialCount, maximumCount); 025 } 026 027 /** 028 * Constructor. Maximum count is Integer.MAX_VALUE. 029 * 030 * @param initialCount initial value for the semaphore's internal counter 031 */ 032 public Semaphore(int initialCount) { 033 this(initialCount, Integer.MAX_VALUE); 034 } 035 036 /** Constructor. Initial count is 0, maximum count is Integer.MAX_VALUE. */ 037 public Semaphore() { 038 this(0, Integer.MAX_VALUE); 039 } 040 041 @Override 042 public void close() { 043 if (m_handle != 0) { 044 WPIUtilJNI.destroySemaphore(m_handle); 045 m_handle = 0; 046 } 047 } 048 049 /** 050 * Gets the semaphore handle (e.g. for waitForObject). 051 * 052 * @return handle 053 */ 054 public int getHandle() { 055 return m_handle; 056 } 057 058 /** 059 * Releases N counts of the semaphore. 060 * 061 * @param releaseCount amount to add to semaphore's internal counter; must be positive 062 * @return True on successful release, false on failure (e.g. release count would exceed maximum 063 * value, or handle invalid) 064 */ 065 public boolean release(int releaseCount) { 066 return WPIUtilJNI.releaseSemaphore(m_handle, releaseCount); 067 } 068 069 /** 070 * Releases 1 count of the semaphore. 071 * 072 * @return True on successful release, false on failure (e.g. release count would exceed maximum 073 * value, or handle invalid) 074 */ 075 public boolean release() { 076 return release(1); 077 } 078 079 private int m_handle; 080}