Lock.hx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package java.vm;
  2. import java.Lib;
  3. import java.lang.System;
  4. using haxe.Int64;
  5. @:native('haxe.java.vm.Lock') class Lock
  6. {
  7. @:private @:volatile var releasedCount = 0;
  8. /**
  9. Creates a new lock, which is initially locked
  10. **/
  11. public function new()
  12. {
  13. }
  14. /**
  15. Waits for a lock to be released and acquire it.
  16. If `timeout` (in seconds) is not null and expires then the returned value is false
  17. **/
  18. public function wait(?timeout : Float) : Bool
  19. {
  20. var ret = false;
  21. java.Lib.lock(this,
  22. {
  23. if (--releasedCount < 0)
  24. {
  25. if (timeout == null)
  26. {
  27. // since .notify() is asynchronous, this `while` is needed
  28. // because there is a very remote possibility of release() awaking a thread,
  29. // but before it releases, another thread calls wait - and since the release count
  30. // is still positive, it will get the lock.
  31. while( releasedCount < 0 )
  32. {
  33. try
  34. {
  35. untyped __java__("this.wait()");
  36. }
  37. catch(e:java.lang.InterruptedException)
  38. {
  39. }
  40. }
  41. } else {
  42. var timeout:haxe.Int64 = cast timeout * 1000;
  43. var cur = System.currentTimeMillis(),
  44. max = cur.add(timeout);
  45. // see above comment about this while loop
  46. while ( releasedCount < 0 && cur.compare(max) < 0 )
  47. {
  48. try
  49. {
  50. var t = max.sub(cur);
  51. untyped __java__("this.wait({0})",t);
  52. cur = System.currentTimeMillis();
  53. }
  54. catch(e:java.lang.InterruptedException)
  55. {
  56. }
  57. }
  58. }
  59. }
  60. ret = this.releasedCount >= 0;
  61. if (!ret)
  62. this.releasedCount++; //timed out
  63. });
  64. return ret;
  65. }
  66. /**
  67. Release a lock. The thread does not need to own the lock to be able to release it.
  68. If a lock is released several times, it can be acquired as many times
  69. **/
  70. public function release()
  71. {
  72. untyped __lock__(this,
  73. {
  74. if (++releasedCount >= 0)
  75. {
  76. untyped this.notify();
  77. }
  78. });
  79. }
  80. }