aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java
blob: 06ce54368522c241813340a1d5effdd38ac51e88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.jogamp.nativewindow.impl;

import javax.media.nativewindow.*;

//
// Reentrance locking toolkit
// 
public class RecursiveToolkitLock implements ToolkitLock {
    private Thread owner;
    private int recursionCount;
    private Exception lockedStack = null;
    private static final long timeout = 3000;  // maximum wait 3s

    public Exception getLockedStack() {
        return lockedStack;
    }

    public Thread getOwner() {
        return owner;
    }

    public boolean isOwner() {
        return isOwner(Thread.currentThread());
    }

    public synchronized boolean isOwner(Thread thread) {
        return owner == thread ;
    }

    public synchronized boolean isLocked() {
        return null != owner;
    }

    /** Recursive and blocking lockSurface() implementation */
    public synchronized void lock() {
        Thread cur = Thread.currentThread();
        if (owner == cur) {
            ++recursionCount;
            return;
        }

        long ts = System.currentTimeMillis();
        while (owner != null && (System.currentTimeMillis()-ts) < timeout) {
            try {
                wait(timeout);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        if(owner != null) {
            lockedStack.printStackTrace();
            throw new RuntimeException("Waited "+timeout+"ms for: "+owner+" - "+cur);
        }
        owner = cur;
        lockedStack = new Exception("Previously locked by "+owner);
    }
    

    /** Recursive and unblocking unlockSurface() implementation */
    public synchronized void unlock() {
        unlock(null);
    }

    /** Recursive and unblocking unlockSurface() implementation */
    public synchronized void unlock(Runnable releaseAfterUnlockBeforeNotify) {
        Thread cur = Thread.currentThread();
        if (owner != cur) {
            lockedStack.printStackTrace();
            throw new RuntimeException(cur+": Not owner, owner is "+owner);
        }
        if (recursionCount > 0) {
            --recursionCount;
            return;
        }
        owner = null;
        lockedStack = null;
        if(null!=releaseAfterUnlockBeforeNotify) {
            releaseAfterUnlockBeforeNotify.run();
        }
        notifyAll();
    }
}