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