aboutsummaryrefslogtreecommitdiffstats
path: root/native/jni/src/utils/exclusive_ownership_pointer.h
blob: 3cf78954ade504d2246866f065c6739e5555ceca (about) (plain) (blame)
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
/*
 * Copyright (C) 2013, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H
#define LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H

#include "defines.h"

namespace latinime {

template<class T>
class ExclusiveOwnershipPointer {
 public:
    // This instance become an owner of the raw pointer.
    ExclusiveOwnershipPointer(T *const rawPointer)
            : mPointer(rawPointer),
              mSharedOwnerPtr(new (ExclusiveOwnershipPointer<T> *)(this)) {}

    // Move the ownership.
    ExclusiveOwnershipPointer(const ExclusiveOwnershipPointer<T> &pointer)
            : mPointer(pointer.mPointer), mSharedOwnerPtr(pointer.mSharedOwnerPtr) {
        transferOwnership(&pointer);
    }

    ~ExclusiveOwnershipPointer() {
        deletePointersIfHavingOwnership();
    }

    // Move the ownership.
    ExclusiveOwnershipPointer<T> &operator=(const ExclusiveOwnershipPointer<T> &pointer) {
        // Delete pointers when this is an owner of another pointer.
        deletePointersIfHavingOwnership();
        mPointer = pointer.mPointer;
        mSharedOwnerPtr = pointer.mSharedOwnerPtr;
        transferOwnership(pointer);
        return *this;
    }

    T *get() const {
        return mPointer;
    }

 private:
    // This class allows to copy and assign and ensures only one instance has the ownership of the
    // managed pointer.

    ExclusiveOwnershipPointer() : mPointer(0), mSharedOwnerPtr(0) {}

    void transferOwnership(const ExclusiveOwnershipPointer<T> *const src) {
        if (*mSharedOwnerPtr != src) {
           AKLOGE("Failed to transfer the ownership because src is not the current owner."
                   "src: %p, owner: %p", src, *mSharedOwnerPtr);
           ASSERT(false);
           return;
        }
        // Transfer the ownership from src to this instance.
        *mSharedOwnerPtr = this;
    }

    void deletePointersIfHavingOwnership() {
        if (mSharedOwnerPtr && *mSharedOwnerPtr == this) {
            if (mPointer) {
                if (DEBUG_DICT) {
                    AKLOGI("Releasing pointer: %p", mPointer);
                }
                delete mPointer;
            }
            delete mSharedOwnerPtr;
        }
    }

    T *mPointer;
    // mSharedOwnerPtr points a shared memory space where the instance which has the ownership is
    // stored.
    ExclusiveOwnershipPointer<T> **mSharedOwnerPtr;
};
} // namespace latinime
#endif /* LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H */