1 /* @file value.h
2    concurrency helpers DiagStr
3 */
4 
5 
6 /**
7  *    Copyright (C) 2018-present MongoDB, Inc.
8  *
9  *    This program is free software: you can redistribute it and/or modify
10  *    it under the terms of the Server Side Public License, version 1,
11  *    as published by MongoDB, Inc.
12  *
13  *    This program is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    Server Side Public License for more details.
17  *
18  *    You should have received a copy of the Server Side Public License
19  *    along with this program. If not, see
20  *    <http://www.mongodb.com/licensing/server-side-public-license>.
21  *
22  *    As a special exception, the copyright holders give permission to link the
23  *    code of portions of this program with the OpenSSL library under certain
24  *    conditions as described in each individual source file and distribute
25  *    linked combinations including the program with the OpenSSL library. You
26  *    must comply with the Server Side Public License in all respects for
27  *    all of the code used other than as permitted herein. If you modify file(s)
28  *    with this exception, you may extend this exception to your version of the
29  *    file(s), but you are not obligated to do so. If you do not wish to do so,
30  *    delete this exception statement from your version. If you delete this
31  *    exception statement from all source files in the program, then also delete
32  *    it in the license file.
33  */
34 
35 #pragma once
36 
37 #include "spin_lock.h"
38 
39 namespace mongo {
40 
41 // todo: rename this to ThreadSafeString or something
42 /** there is now one mutex per DiagStr.  If you have hundreds or millions of
43     DiagStrs you'll need to do something different.
44 */
45 class DiagStr {
46     mutable SpinLock m;
47     std::string _s;
48 
49 public:
DiagStr(const DiagStr & r)50     DiagStr(const DiagStr& r) : _s(r.get()) {}
DiagStr(const std::string & r)51     DiagStr(const std::string& r) : _s(r) {}
DiagStr()52     DiagStr() {}
empty()53     bool empty() const {
54         scoped_spinlock lk(m);
55         return _s.empty();
56     }
get()57     std::string get() const {
58         scoped_spinlock lk(m);
59         return _s;
60     }
set(const char * s)61     void set(const char* s) {
62         scoped_spinlock lk(m);
63         _s = s;
64     }
set(const std::string & s)65     void set(const std::string& s) {
66         scoped_spinlock lk(m);
67         _s = s;
68     }
string()69     operator std::string() const {
70         return get();
71     }
72     void operator=(const std::string& s) {
73         set(s);
74     }
75     void operator=(const DiagStr& rhs) {
76         set(rhs.get());
77     }
78 
79     // == is not defined.  use get() == ... instead.  done this way so one thinks about if composing
80     // multiple operations
81     bool operator==(const std::string& s) const;
82 };
83 }
84