CallbackMemoryIO.java

  1. package org.jruby.ext.ffi.jffi;

  2. import com.kenai.jffi.Closure;
  3. import org.jruby.Ruby;
  4. import org.jruby.ext.ffi.AllocatedDirectMemoryIO;
  5. import org.jruby.ext.ffi.InvalidMemoryIO;

  6. import java.util.concurrent.atomic.AtomicBoolean;

  7. /**
  8.  * An implementation of MemoryIO that throws exceptions on any attempt to read/write
  9.  * the callback memory area (which is code).
  10.  *
  11.  * This also keeps the callback alive via the handle member, as long as this
  12.  * CallbackMemoryIO instance is contained in a valid Callback pointer.
  13.  */
  14. final class CallbackMemoryIO extends InvalidMemoryIO implements AllocatedDirectMemoryIO {
  15.     private final Closure.Handle handle;
  16.     private volatile boolean released;
  17.     private volatile boolean unmanaged;
  18.     private Object proc;

  19.     public CallbackMemoryIO(Ruby runtime, Closure.Handle handle, Object proc) {
  20.         super(runtime, true, handle.getAddress(), "cannot access closure trampoline memory");
  21.         this.handle = handle;
  22.         this.proc = proc;
  23.     }

  24.     public CallbackMemoryIO(Ruby runtime, Closure.Handle handle) {
  25.         this(runtime, handle, null);
  26.     }

  27.     public synchronized void free() {
  28.         if (!released) {
  29.             this.proc = null;
  30.             handle.dispose();
  31.             released = true;
  32.             unmanaged = true;
  33.         }
  34.     }

  35.     public synchronized void setAutoRelease(boolean autorelease) {
  36.         if (isAutoRelease() != autorelease) {
  37.             handle.setAutoRelease(autorelease);
  38.             unmanaged = !autorelease;
  39.         }
  40.     }

  41.     public boolean isAutoRelease() {
  42.         return !unmanaged;
  43.     }
  44. }