GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
SingletonInstance.java
Go to the documentation of this file.
1/**
2 * Copyright 2011 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.common.util.locks;
30
31import java.io.File;
32
33import jogamp.common.util.locks.SingletonInstanceFileLock;
34import jogamp.common.util.locks.SingletonInstanceServerSocket;
35
36public abstract class SingletonInstance implements Lock {
37
38 protected static final boolean DEBUG = true;
39
40 public static SingletonInstance createFileLock(final long poll_ms, final String lockFileBasename) {
41 return new SingletonInstanceFileLock(poll_ms, lockFileBasename);
42 }
43
44 public static SingletonInstance createFileLock(final long poll_ms, final File lockFile) {
45 return new SingletonInstanceFileLock(poll_ms, lockFile);
46 }
47
48 /**
49 * A user shall use <b>ephemeral ports</b>:
50 * <ul>
51 * <li>IANA suggests 49152 to 65535 as "dynamic and/or private ports".</li>
52 * <li>Many GNU/Linux kernels use 32768 to 61000.</li>
53 * <li>FreeBSD >= 4.6 uses the IANA port range.</li>
54 * <li>FreeBSD < 4.6 and BSD use ports 1024 through 4999.</li>
55 * <li>Microsoft Windows operating systems through Server 2003 use the range 1025 to 5000</li>
56 * <li>Windows Vista, Windows 7, and Server 2008 use the IANA range.</li>
57 * </ul>
58 * @param pollPeriod
59 * @param portNumber to be used for this single instance server socket.
60 */
61 public static SingletonInstance createServerSocket(final long poll_ms, final int portNumber) {
62 return new SingletonInstanceServerSocket(poll_ms, portNumber);
63 }
64
65 protected SingletonInstance(final long poll_ms) {
66 this.poll_ms = Math.max(10, poll_ms);
67 }
68
69 public final long getPollPeriod() { return poll_ms; }
70 public abstract String getName();
71 @Override
72 public final String toString() { return getName(); }
73
74 @Override
75 public synchronized void lock() throws RuntimeException {
76 try {
77 do {
78 if(tryLock(TIMEOUT)) {
79 return;
80 }
81 } while ( true ) ;
82 } catch ( final RuntimeException ie ) {
83 throw new RuntimeException(ie);
84 }
85 }
86
87 @Override
88 public synchronized boolean tryLock(long maxwait) throws RuntimeException {
89 if(locked) {
90 return true;
91 }
92 final long t0 = System.currentTimeMillis();
93 int i=0;
94 try {
95 do {
96 final long t1 = System.currentTimeMillis();
97 locked = tryLockImpl();
98 if(locked) {
99 if( DEBUG ) {
100 final long t2 = System.currentTimeMillis();
101 System.err.println(infoPrefix(t2)+" +++ "+getName()+" - Locked within "+(t2-t0)+" ms, "+(i+1)+" attempts");
102 }
103 return true;
104 }
105 if( DEBUG && 0==i ) {
106 System.err.println(infoPrefix(System.currentTimeMillis())+" III "+getName()+" - Wait for lock");
107 }
108 Thread.sleep(poll_ms);
109 maxwait -= System.currentTimeMillis()-t1;
110 i++;
111 } while ( 0 < maxwait ) ;
112 } catch ( final InterruptedException ie ) {
113 final long t2 = System.currentTimeMillis();
114 throw new RuntimeException(infoPrefix(t2)+" EEE (1) "+getName()+" - couldn't get lock within "+(t2-t0)+" ms, "+i+" attempts", ie);
115 }
116 if( DEBUG ) {
117 final long t2 = System.currentTimeMillis();
118 System.err.println(infoPrefix(t2)+" +++ EEE (2) "+getName()+" - couldn't get lock within "+(t2-t0)+" ms, "+i+" attempts");
119 }
120 return false;
121 }
122 protected abstract boolean tryLockImpl();
123
124 @Override
125 public void unlock() throws RuntimeException {
126 final long t0 = System.currentTimeMillis();
127 if(locked) {
128 locked = !unlockImpl();
129 if( DEBUG ) {
130 final long t2 = System.currentTimeMillis();
131 System.err.println(infoPrefix(t2)+" --- "+getName()+" - Unlock "+ ( locked ? "failed" : "ok" ) + " within "+(t2-t0)+" ms");
132 }
133 }
134 }
135 protected abstract boolean unlockImpl();
136
137 @Override
138 public synchronized boolean isLocked() {
139 return locked;
140 }
141
142 protected String infoPrefix(final long currentMillis) {
143 return "SLOCK [T "+Thread.currentThread().getName()+" @ "+currentMillis+" ms";
144 }
145 protected String infoPrefix() {
146 return infoPrefix(System.currentTimeMillis());
147 }
148
149 private final long poll_ms;
150 private boolean locked = false;
151}
static SingletonInstance createFileLock(final long poll_ms, final File lockFile)
synchronized boolean tryLock(long maxwait)
Blocking until the lock is acquired by this Thread or maxwait in ms is reached.
static SingletonInstance createFileLock(final long poll_ms, final String lockFileBasename)
static SingletonInstance createServerSocket(final long poll_ms, final int portNumber)
A user shall use ephemeral ports:
synchronized boolean isLocked()
Query if locked.
synchronized void lock()
Blocking until the lock is acquired by this Thread or TIMEOUT is reached.
Specifying a thread blocking lock implementation.
Definition: Lock.java:36
static final long TIMEOUT
The TIMEOUT for lock() in ms, defaults to DEFAULT_TIMEOUT.
Definition: Lock.java:54