1/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * DEPRECATED.  DO NOT USE FOR NEW CODE.
19 */
20
21#ifndef ANDROID_SHARED_BUFFER_H
22#define ANDROID_SHARED_BUFFER_H
23
24#include <atomic>
25#include <stdint.h>
26#include <sys/types.h>
27
28// ---------------------------------------------------------------------------
29
30namespace android {
31
32class SharedBuffer
33{
34public:
35
36    /* flags to use with release() */
37    enum {
38        eKeepStorage = 0x00000001
39    };
40
41    /*! allocate a buffer of size 'size' and acquire() it.
42     *  call release() to free it.
43     */
44    static          SharedBuffer*           alloc(size_t size);
45
46    /*! free the memory associated with the SharedBuffer.
47     * Fails if there are any users associated with this SharedBuffer.
48     * In other words, the buffer must have been release by all its
49     * users.
50     */
51    static          void                    dealloc(const SharedBuffer* released);
52
53    //! access the data for read
54    inline          const void*             data() const;
55
56    //! access the data for read/write
57    inline          void*                   data();
58
59    //! get size of the buffer
60    inline          size_t                  size() const;
61
62    //! get back a SharedBuffer object from its data
63    static  inline  SharedBuffer*           bufferFromData(void* data);
64
65    //! get back a SharedBuffer object from its data
66    static  inline  const SharedBuffer*     bufferFromData(const void* data);
67
68    //! get the size of a SharedBuffer object from its data
69    static  inline  size_t                  sizeFromData(const void* data);
70
71    //! edit the buffer (get a writtable, or non-const, version of it)
72                    SharedBuffer*           edit() const;
73
74    //! edit the buffer, resizing if needed
75                    SharedBuffer*           editResize(size_t size) const;
76
77    //! like edit() but fails if a copy is required
78                    SharedBuffer*           attemptEdit() const;
79
80    //! resize and edit the buffer, loose it's content.
81                    SharedBuffer*           reset(size_t size) const;
82
83    //! acquire/release a reference on this buffer
84                    void                    acquire() const;
85
86    /*! release a reference on this buffer, with the option of not
87     * freeing the memory associated with it if it was the last reference
88     * returns the previous reference count
89     */
90                    int32_t                 release(uint32_t flags = 0) const;
91
92    //! returns wether or not we're the only owner
93    inline          bool                    onlyOwner() const;
94
95
96private:
97        inline SharedBuffer() { }
98        inline ~SharedBuffer() { }
99        SharedBuffer(const SharedBuffer&);
100        SharedBuffer& operator = (const SharedBuffer&);
101
102        // Must be sized to preserve correct alignment.
103        mutable std::atomic<int32_t>        mRefs;
104                size_t                      mSize;
105                uint32_t                    mReserved[2];
106};
107
108static_assert(sizeof(SharedBuffer) % 8 == 0
109        && (sizeof(size_t) > 4 || sizeof(SharedBuffer) == 16),
110        "SharedBuffer has unexpected size");
111
112// ---------------------------------------------------------------------------
113
114const void* SharedBuffer::data() const {
115    return this + 1;
116}
117
118void* SharedBuffer::data() {
119    return this + 1;
120}
121
122size_t SharedBuffer::size() const {
123    return mSize;
124}
125
126SharedBuffer* SharedBuffer::bufferFromData(void* data) {
127    return data ? static_cast<SharedBuffer *>(data)-1 : 0;
128}
129
130const SharedBuffer* SharedBuffer::bufferFromData(const void* data) {
131    return data ? static_cast<const SharedBuffer *>(data)-1 : 0;
132}
133
134size_t SharedBuffer::sizeFromData(const void* data) {
135    return data ? bufferFromData(data)->mSize : 0;
136}
137
138bool SharedBuffer::onlyOwner() const {
139    return (mRefs.load(std::memory_order_acquire) == 1);
140}
141
142}; // namespace android
143
144// ---------------------------------------------------------------------------
145
146#endif // ANDROID_VECTOR_H
147