1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.mojo.system.impl; 6 7 import android.util.Log; 8 9 import org.chromium.mojo.system.Core; 10 import org.chromium.mojo.system.Core.HandleSignals; 11 import org.chromium.mojo.system.Core.WaitResult; 12 import org.chromium.mojo.system.Handle; 13 import org.chromium.mojo.system.UntypedHandle; 14 15 /** 16 * Implementation of {@link Handle}. 17 */ 18 abstract class HandleBase implements Handle { 19 20 private static final String TAG = "HandleImpl"; 21 22 /** 23 * The pointer to the scoped handle owned by this object. 24 */ 25 private int mMojoHandle; 26 27 /** 28 * The core implementation. Will be used to delegate all behavior. 29 */ 30 protected CoreImpl mCore; 31 32 /** 33 * Base constructor. Takes ownership of the passed handle. 34 */ HandleBase(CoreImpl core, int mojoHandle)35 HandleBase(CoreImpl core, int mojoHandle) { 36 mCore = core; 37 mMojoHandle = mojoHandle; 38 } 39 40 /** 41 * Constructor for transforming {@link HandleBase} into a specific one. It is used to transform 42 * an {@link UntypedHandle} into a typed one, or any handle into an {@link UntypedHandle}. 43 */ HandleBase(HandleBase other)44 protected HandleBase(HandleBase other) { 45 mCore = other.mCore; 46 HandleBase otherAsHandleImpl = other; 47 int mojoHandle = otherAsHandleImpl.mMojoHandle; 48 otherAsHandleImpl.mMojoHandle = CoreImpl.INVALID_HANDLE; 49 mMojoHandle = mojoHandle; 50 } 51 52 /** 53 * @see org.chromium.mojo.system.Handle#close() 54 */ 55 @Override close()56 public void close() { 57 if (mMojoHandle != CoreImpl.INVALID_HANDLE) { 58 // After a close, the handle is invalid whether the close succeed or not. 59 int handle = mMojoHandle; 60 mMojoHandle = CoreImpl.INVALID_HANDLE; 61 mCore.close(handle); 62 } 63 } 64 65 /** 66 * @see org.chromium.mojo.system.Handle#wait(HandleSignals, long) 67 */ 68 @Override wait(HandleSignals signals, long deadline)69 public WaitResult wait(HandleSignals signals, long deadline) { 70 return mCore.wait(this, signals, deadline); 71 } 72 73 /** 74 * @see org.chromium.mojo.system.Handle#isValid() 75 */ 76 @Override isValid()77 public boolean isValid() { 78 return mMojoHandle != CoreImpl.INVALID_HANDLE; 79 } 80 81 /** 82 * @see org.chromium.mojo.system.Handle#toUntypedHandle() 83 */ 84 @Override toUntypedHandle()85 public UntypedHandle toUntypedHandle() { 86 return new UntypedHandleImpl(this); 87 } 88 89 /** 90 * @see org.chromium.mojo.system.Handle#getCore() 91 */ 92 @Override getCore()93 public Core getCore() { 94 return mCore; 95 } 96 97 /** 98 * @see Handle#releaseNativeHandle() 99 */ 100 @Override releaseNativeHandle()101 public int releaseNativeHandle() { 102 int result = mMojoHandle; 103 mMojoHandle = CoreImpl.INVALID_HANDLE; 104 return result; 105 } 106 107 /** 108 * Getter for the native scoped handle. 109 * 110 * @return the native scoped handle. 111 */ getMojoHandle()112 int getMojoHandle() { 113 return mMojoHandle; 114 } 115 116 /** 117 * invalidate the handle. The caller must ensures that the handle does not leak. 118 */ invalidateHandle()119 void invalidateHandle() { 120 mMojoHandle = CoreImpl.INVALID_HANDLE; 121 } 122 123 /** 124 * Close the handle if it is valid. Necessary because we cannot let handle leak, and we cannot 125 * ensure that every handle will be manually closed. 126 * 127 * @see java.lang.Object#finalize() 128 */ 129 @Override finalize()130 protected final void finalize() throws Throwable { 131 if (isValid()) { 132 // This should not happen, as the user of this class should close the handle. Adding a 133 // warning. 134 Log.w(TAG, "Handle was not closed."); 135 // Ignore result at this point. 136 mCore.closeWithResult(mMojoHandle); 137 } 138 super.finalize(); 139 } 140 141 } 142