001/*
002 * ============================================================================
003 *  Copyright © 2002-2026 by Thomas Thrien.
004 *  All Rights Reserved.
005 * ============================================================================
006 *  Licensed to the public under the agreements of the GNU Lesser General Public
007 *  License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *       http://www.gnu.org/licenses/lgpl.html
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 *  License for the specific language governing permissions and limitations
015 *  under the License.
016 */
017
018package org.tquadrat.foundation.lang.internal;
019
020import static org.apiguardian.api.API.Status.INTERNAL;
021import static org.apiguardian.api.API.Status.STABLE;
022
023import java.io.Serial;
024import java.util.concurrent.Semaphore;
025
026import org.apiguardian.api.API;
027import org.tquadrat.foundation.annotation.ClassVersion;
028import org.tquadrat.foundation.lang.AutoSemaphore;
029
030/**
031 *  <p>{@summary The implementation of
032 *  {@link AutoSemaphore}.} At the same time, this class extends
033 *  {@link Semaphore}.</p>
034 *
035 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
036 *  @version $Id: AutoSemaphoreImpl.java 1258 2026-06-04 18:33:06Z tquadrat $
037 *  @since 0.25.2
038 *
039 *  @UMLGraph.link
040 */
041@ClassVersion( sourceVersion = "$Id: AutoSemaphoreImpl.java 1258 2026-06-04 18:33:06Z tquadrat $" )
042@API( status = STABLE, since = "0.4.8" )
043public final class AutoSemaphoreImpl extends Semaphore implements AutoSemaphore
044{
045        /*---------------*\
046    ====** Inner Classes **====================================================
047        \*---------------*/
048    /**
049     *  <p>{@summary The implementation of
050     *  {@link AutoSemaphore.Token}.}</p>
051     *
052     *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
053     *  @version $Id: AutoSemaphoreImpl.java 1258 2026-06-04 18:33:06Z tquadrat $
054     *  @since 0.25.2
055     *
056     *  @UMLGraph.link
057     */
058    @ClassVersion( sourceVersion = "$Id: AutoSemaphoreImpl.java 1258 2026-06-04 18:33:06Z tquadrat $" )
059    @API( status = INTERNAL, since = "0.25.2" )
060    public final class TokenImpl implements AutoSemaphore.Token
061    {
062            /*------------*\
063        ====** Attributes **===================================================
064            \*------------*/
065        /**
066         *  The number of permits to release on close.
067         */
068        private final int m_Permits;
069
070            /*--------------*\
071        ====** Constructors **=================================================
072            \*--------------*/
073        /**
074         *  Creates a new instance of {@code TokenImpl}.
075         *
076         *  @param  permits The number of the acquired permits.
077         */
078        public TokenImpl( final int permits )
079        {
080            m_Permits = permits;
081        }   //  TokenImpl()
082
083            /*---------*\
084        ====** Methods **======================================================
085            \*---------*/
086        /**
087         *  {@inheritDoc}
088         */
089        @Override
090        public final void close()
091        {
092            AutoSemaphoreImpl.this.release( m_Permits );
093        }   //  close()
094
095        /**
096         *  {@inheritDoc}
097         */
098        @Override
099        public final Semaphore getSemaphore() { return AutoSemaphoreImpl.this; }
100    }
101    //  class TokenImpl
102
103        /*------------------------*\
104    ====** Static Initialisations **===========================================
105        \*------------------------*/
106    /**
107     *  The serial version UID for objects of this class: {@value}.
108     *
109     *  @hidden
110     */
111    @Serial
112    private static final long serialVersionUID = 539879857L;
113
114        /*--------------*\
115    ====** Constructors **=====================================================
116        \*--------------*/
117    /**
118     *  Creates an {@code AutoSemaphoreImpl} instance with the given number of
119     *  permits and non-fair fairness setting.
120     *
121     *  @param  permits The initial number of permits available. This value may
122     *      be negative, in which case releases must occur before any acquires
123     *      will be granted.
124     */
125    public AutoSemaphoreImpl( final int permits )
126    {
127        super( permits );
128    }   //  AutoSemaphoreImpl()
129
130    /**
131     *  Creates an {@code AutoSemaphoreImpl} instance with the given number of
132     *  permits and the given fairness setting.
133     *
134     *  @param  permits The initial number of permits available. This value may
135     *      be negative, in which case releases must occur before any acquires
136     *      will be granted.
137     *  @param  fair    {@true} if this semaphore will guarantee first-in
138     *      first-out granting of permits under contention, else {@false}.
139     */
140    public AutoSemaphoreImpl( final int permits, final boolean fair )
141    {
142        super( permits, fair );
143    }   //  AutoSemaphoreImpl()
144
145        /*---------*\
146    ====** Methods **==========================================================
147        \*---------*/
148    /**
149     *  {@inheritDoc}
150     */
151    @Override
152    @SuppressWarnings( "ReturnOfInnerClass" )
153    public final Token acquireToken( final int permits ) throws InterruptedException, IllegalArgumentException
154    {
155        acquire( permits );
156        final var retValue = new TokenImpl( permits );
157
158        //---* Done *----------------------------------------------------------
159        return retValue;
160    }   //  acquireToken()
161
162    /**
163     *  {@inheritDoc}
164     */
165    @Override
166    @SuppressWarnings( "ReturnOfInnerClass" )
167    public final Token acquireTokenUninterruptibly( final int permits ) throws IllegalArgumentException
168    {
169        acquireUninterruptibly( permits );
170        final var retValue = new TokenImpl( permits );
171
172        //---* Done *----------------------------------------------------------
173        return retValue;
174    }   //  acquireTokenUninterruptibly()
175
176    /**
177     *  {@inheritDoc}
178     */
179    @Override
180    public final Semaphore getSemaphore() { return this; }
181}
182//  class AutoSemaphore
183
184/*
185 *  End of File
186 */