2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/shared-string.h"
20 ///////////////////////////////////////////////////////////////////////////////
22 SharedStringData::InternMap
SharedStringData::s_intern
;
24 SharedStringData::SharedStringData(const std::string
&data
) : m_data(data
) {
28 int SharedStringData::decAtomicCount() const {
30 int cur
= m_count
.fetch_and_decrement() - 1;
32 // Only left in intern map. While this data is still in the
33 // the map we consider this data dying. All new Creates will
34 // overwrite the SharedStringData* in the slot and not use this one.
35 InternMap::accessor acc
;
36 bool found
= s_intern
.find(acc
, m_data
);
38 // May not be found or may not be acc->second if other thread overwrote.
39 // Safe to just delete self.
40 if (found
&& acc
->second
== this) {
48 void SharedStringData::atomicRelease() {
52 const std::string
&SharedStringData::getString() const {
56 void SharedStringData::Create(InternMap::accessor
&acc
,
57 const std::string
&data
) {
58 if (s_intern
.insert(acc
, data
)) {
59 acc
->second
= new SharedStringData(acc
->first
);
62 // Danger is now that the data is dying. We must not acquire a reference
63 // if it in that state.
65 int cur
= acc
->second
->m_count
;
67 acc
->second
= new SharedStringData(acc
->first
);
70 // Never change refcount of 0 to refcount of 1, impossible
71 // to revive a dying SharedStringData.
72 if (acc
->second
->m_count
.compare_and_swap(cur
+ 1, cur
) == cur
) {
75 // Other thread must have inc/dec ref'd since we got cur
79 SharedString
&SharedString::operator=(const std::string
&data
) {
81 SharedStringData::InternMap::accessor acc
;
82 SharedStringData::Create(acc
, data
);
83 // Ref count already incremented in Create
84 overwrite_unsafe(acc
->second
);
88 ///////////////////////////////////////////////////////////////////////////////