summaryrefslogtreecommitdiff
path: root/mojo/android/system/src/org/chromium/mojo/system/impl/HandleBase.java
blob: 4d149a48d715d43134f1aef09a0624f4fb4021bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.mojo.system.impl;

import android.util.Log;

import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.Core.HandleSignalsState;
import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.UntypedHandle;

/**
 * Implementation of {@link Handle}.
 */
abstract class HandleBase implements Handle {

    private static final String TAG = "HandleImpl";

    /**
     * The pointer to the scoped handle owned by this object.
     */
    private int mMojoHandle;

    /**
     * The core implementation. Will be used to delegate all behavior.
     */
    protected CoreImpl mCore;

    /**
     * Base constructor. Takes ownership of the passed handle.
     */
    HandleBase(CoreImpl core, int mojoHandle) {
        mCore = core;
        mMojoHandle = mojoHandle;
    }

    /**
     * Constructor for transforming {@link HandleBase} into a specific one. It is used to transform
     * an {@link UntypedHandle} into a typed one, or any handle into an {@link UntypedHandle}.
     */
    protected HandleBase(HandleBase other) {
        mCore = other.mCore;
        HandleBase otherAsHandleImpl = other;
        int mojoHandle = otherAsHandleImpl.mMojoHandle;
        otherAsHandleImpl.mMojoHandle = CoreImpl.INVALID_HANDLE;
        mMojoHandle = mojoHandle;
    }

    /**
     * @see org.chromium.mojo.system.Handle#close()
     */
    @Override
    public void close() {
        if (mMojoHandle != CoreImpl.INVALID_HANDLE) {
            // After a close, the handle is invalid whether the close succeed or not.
            int handle = mMojoHandle;
            mMojoHandle = CoreImpl.INVALID_HANDLE;
            mCore.close(handle);
        }
    }

    /**
     * @see org.chromium.mojo.system.Handle#querySignalsState()
     */
    @Override
    public HandleSignalsState querySignalsState() {
        return mCore.queryHandleSignalsState(mMojoHandle);
    }

    /**
     * @see org.chromium.mojo.system.Handle#isValid()
     */
    @Override
    public boolean isValid() {
        return mMojoHandle != CoreImpl.INVALID_HANDLE;
    }

    /**
     * @see org.chromium.mojo.system.Handle#toUntypedHandle()
     */
    @Override
    public UntypedHandle toUntypedHandle() {
        return new UntypedHandleImpl(this);
    }

    /**
     * @see org.chromium.mojo.system.Handle#getCore()
     */
    @Override
    public Core getCore() {
        return mCore;
    }

    /**
     * @see Handle#releaseNativeHandle()
     */
    @Override
    public int releaseNativeHandle() {
        int result = mMojoHandle;
        mMojoHandle = CoreImpl.INVALID_HANDLE;
        return result;
    }

    /**
     * Getter for the native scoped handle.
     *
     * @return the native scoped handle.
     */
    int getMojoHandle() {
        return mMojoHandle;
    }

    /**
     * invalidate the handle. The caller must ensures that the handle does not leak.
     */
    void invalidateHandle() {
        mMojoHandle = CoreImpl.INVALID_HANDLE;
    }

    /**
     * Close the handle if it is valid. Necessary because we cannot let handle leak, and we cannot
     * ensure that every handle will be manually closed.
     *
     * @see java.lang.Object#finalize()
     */
    @Override
    protected final void finalize() throws Throwable {
        if (isValid()) {
            // This should not happen, as the user of this class should close the handle. Adding a
            // warning.
            Log.w(TAG, "Handle was not closed.");
            // Ignore result at this point.
            mCore.closeWithResult(mMojoHandle);
        }
        super.finalize();
    }

}