001/* ---------------------------------------------------------------------------- 002 * This file was automatically generated by SWIG (http://www.swig.org). 003 * Version 4.0.2 004 * 005 * Do not make changes to this file unless you know what you are doing--modify 006 * the SWIG interface file instead. 007 * ----------------------------------------------------------------------------- */ 008 009package com.avpkit.ferry; 010 011/** 012 * Parent of all Ferry objects -- it mains reference counts<br> 013 * in native code.<br> 014 * <p><br> 015 * RefCounted objects cannot be made with new. They must be<br> 016 * constructed with special factory methods, usually called<br> 017 * make(...).<br> 018 * </p><br> 019 * <h2>Special note for developers in languages other than C++</h2><br> 020 * <p><br> 021 * You should not need to worry about this class very much. Feel<br> 022 * free to ignore it.<br> 023 * </p><br> 024 * <h2>Special note for C++ Users</h2><br> 025 * <p><br> 026 * Users of RefCounted objects in Native (C++) code must make<br> 027 * sure they acquire() a reference to an object if they<br> 028 * intend to keep using it after they have returned from<br> 029 * the method it was passed to, and<br> 030 * must call release() when done to ensure memory is freed.<br> 031 * </p><br> 032 * <p><br> 033 * Methods that return RefCounted objects on the stack are<br> 034 * expected to acquire() the reference for the caller, and<br> 035 * callers <b>must</b> release() any RefCounted object<br> 036 * returned on the stack.<br> 037 * <p><br> 038 * For example:<br> 039 * </p><br> 040 * <code><br> 041 * <pre><br> 042 * RefCounted * methodReturningRefCountedObject();<br> 043 * {<br> 044 * mValueToReturn->acquire(); // acquire for caller<br> 045 * return mValueToReturn; // and return<br> 046 * }<br> 047 * <br> 048 * {<br> 049 * RefCounted *value = methodReturningRefCountedObject();<br> 050 * ...<br> 051 * // caller must release<br> 052 * if (value)<br> 053 * value->release();<br> 054 * }<br> 055 * </pre><br> 056 * </code> 057 */ 058public class RefCounted { 059 // JNIHelper.swg: Start generated code 060 // >>>>>>>>>>>>>>>>>>>>>>>>>>> 061 private volatile long swigCPtr; 062 /** 063 * Internal Only. 064 */ 065 protected boolean swigCMemOwn; 066 private com.avpkit.ferry.JNIReference mRefCounter; 067 private Long mLifecycleReference; 068 069 // the next object looks like it is unused by the compiler, but that's not true; it most 070 // definitely is used :) 071 @SuppressWarnings("unused") 072 private com.avpkit.ferry.JNINativeFinalizer mObjectToForceFinalize; 073 private java.util.concurrent.atomic.AtomicLong mJavaRefCount; 074 075 /** 076 * Internal Only. Not part of public API. 077 */ 078 protected RefCounted(long cPtr, boolean cMemoryOwn) { 079 this(cPtr, cMemoryOwn, new java.util.concurrent.atomic.AtomicLong(0L)); 080 } 081 082 /** 083 * Internal Only. Not part of public API. 084 */ 085 protected RefCounted(long cPtr, boolean cMemoryOwn, 086 java.util.concurrent.atomic.AtomicLong ref) 087 { 088 swigCMemOwn = cMemoryOwn; 089 swigCPtr = cPtr; 090 // Create the reference count that java-only objects will use 091 // to avoid calling acquire and release on copyReference 092 ref.incrementAndGet(); 093 mJavaRefCount = ref; 094 if (swigCPtr != 0) 095 { 096 // This object must: 097 // (a) have no references to any other java object 098 // (b) Have a finalizer that just calls gc() on our JNIMemoryManager 099 // It exists only to force gc() to be called even if someone calls the AVPKit 100 // libraries once and never again 101 mObjectToForceFinalize = new com.avpkit.ferry.JNINativeFinalizer(); 102 // This is what the weak reference will watch; this object should 103 // (a) have no references to any other Java object 104 // (b) MUST NOT have a finalizer 105 // (c) MUST NOT acquire any other references to it except for the strong reference 106 // right here, and the weak reference in mRefCounter 107 mLifecycleReference = new Long(swigCPtr); 108 // Force the creation of a new weak reference, will will actually pin itself 109 // inside the reference class. 110 mRefCounter = JNIReference.createReference( 111 this, 112 mLifecycleReference, swigCPtr, 113 mJavaRefCount); 114 } 115 } 116 117 /** 118 * Internal Only. Not part of public API. 119 * 120 * Get the raw value of the native object that obj is proxying for. 121 * 122 * @param obj The java proxy object for a native object. 123 * @return The raw pointer obj is proxying for. 124 */ 125 public static long getCPtr(RefCounted obj) { 126 if (obj == null) return 0; 127 return obj.getMyCPtr(); 128 } 129 130 /** 131 * Internal Only. Not part of public API. 132 * 133 * Get the raw value of the native object that we're proxying for. 134 * 135 * @return The raw pointer we're proxying for. 136 */ 137 public long getMyCPtr() { 138 if (swigCPtr == 0) throw new NullPointerException("underlying native object already deleted"); 139 return swigCPtr; 140 } 141 142 /** 143 * Releases any underlying native memory and marks this object 144 * as invalid. 145 * <p> 146 * Normally Ferry manages when to release native memory. 147 * </p> 148 * <p> 149 * In the unlikely event you want to control EXACTLY when a native 150 * object is released, each AVPKit object has a {@link #delete()} 151 * method that you can use. Once you call {@link #delete()}, 152 * you must ENSURE your object is never referenced again from 153 * that Java object -- Ferry tries to help you avoid crashes if you 154 * accidentally use an object after deletion but on this but we 155 * cannot offer 100% protection (specifically if another thread 156 * is accessing that object EXACTLY when you {@link #delete()} it). 157 * </p> 158 */ 159 160 public void delete() 161 { 162 if(swigCPtr != 0) { 163 // assigning to an object removes an incorrect java 164 // compiler warning for some 165 // generated files 166 Object object = this; 167 if (object instanceof RefCounted && mRefCounter != null) { 168 mRefCounter.delete(); 169 } else if (swigCMemOwn) { 170 swigCMemOwn = false; 171 } 172 173 } 174 mJavaRefCount = null; 175 mRefCounter = null; 176 mObjectToForceFinalize = null; 177 mLifecycleReference = null; 178 swigCPtr = 0; 179 } 180 181 /** 182 * Create a new RefCounted object that is actually referring to the 183 * exact same underlying native object. 184 * 185 * @return the new Java object. 186 */ 187 public RefCounted copyReference() { 188 if (swigCPtr == 0) 189 return null; 190 else 191 return new RefCounted(swigCPtr, swigCMemOwn, getJavaRefCount()); 192 } 193 194 /** 195 * Internal Only. Do not use. 196 */ 197 protected java.util.concurrent.atomic.AtomicLong getJavaRefCount() 198 { 199 return mJavaRefCount; 200 } 201 202 203 /** 204 * Return the current reference count on this object. 205 * <p> 206 * The number returned represents the value at the instant 207 * the message was called, and the value can change even 208 * before this method returns. Callers are advised not to 209 * depend on the value of this except to check that 210 * the value == 1. 211 * </p> 212 * <p> 213 * If the value returned is one, and you know you have a valid 214 * reference to that object, then congratulations; you are the 215 * only person referencing that object. 216 * </p> 217 * @return The current ref count. 218 */ 219 public long getCurrentRefCount() 220 { 221 return mJavaRefCount.get()+getCurrentNativeRefCount()-1; 222 } 223 // <<<<<<<<<<<<<<<<<<<<<<<<<<< 224 // JNIHelper.swg: End generated code 225 226 227 228 /** 229 * Internal Only. <strong>DO NOT USE FROM JAVA</strong>.<br> 230 * <p><br> 231 * Acquire a reference to this object.<br> 232 * This increments the native internal ref count in native code by +1. <br> 233 * </p><br> 234 * <p><br> 235 * This method is called internally by Ferry in Java, and you should<br> 236 * not call it without knowing what you are doing. But if you do<br> 237 * call it, make sure you call {#release()} once for each call<br> 238 * you make to this method.<br> 239 * </p><br> 240 * @return The refcount after the acquire. Note due to multi-threaded issues, you should not rely on this value,<br> 241 * as it may change before the method returns to you. 242 */ 243 public int acquire() { 244 return FerryJNI.RefCounted_acquire(swigCPtr, this); 245 } 246 247 /** 248 * Internal Only. <strong>DO NOT USE FROM JAVA</strong>.<br> 249 * <p><br> 250 * This decrements the native internal ref count by -1; the object is destroyed if its ref count reaches zero.<br> 251 * </p><br> 252 * <p><br> 253 * This method is called internally by Ferry in Java, and you should<br> 254 * not call it without knowing what you are doing. But if you do<br> 255 * call it, make sure you had previously called {#acquire()} once for each call<br> 256 * to {#release()} you make.<br> 257 * </p><br> 258 * @return The ref count after the release. Note due to multi-threaded issues, you should not rely on this value,<br> 259 * as it may change before the method returns to you. 260 */ 261 public int release() { 262 return FerryJNI.RefCounted_release(swigCPtr, this); 263 } 264 265 /** 266 * Return the current reference count on this object.<br> 267 * <br> 268 * The number returned represents the value at the instant<br> 269 * the message was called, and the value can change even<br> 270 * before this method returns. Callers are advised not to<br> 271 * depend on the value of this except to check that<br> 272 * the value == 1.<br> 273 * <p><br> 274 * If the value returned is one, and you know you have a valid<br> 275 * reference to that object, then congratulations; you are the<br> 276 * only person referencing that object.<br> 277 * </p><br> 278 * @return The current ref count. 279 */ 280 private int getCurrentNativeRefCount() { 281 return FerryJNI.RefCounted_getCurrentNativeRefCount(swigCPtr, this); 282 } 283 284}