summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrédéric Brière <fbriere@fbriere.net>2016-10-03 11:29:00 -0400
committerFrédéric Brière <fbriere@fbriere.net>2016-10-04 17:55:27 -0400
commit2eb954cb34fcb956070896101df4ba78272939fa (patch)
tree33dc1a1d283f88d55f9dae36fa8a180e6da943e2 /src
parenta06681c29a66b7213eef0261d689230ee7515e5e (diff)
downloadtwinkle-2eb954cb34fcb956070896101df4ba78272939fa.tar
twinkle-2eb954cb34fcb956070896101df4ba78272939fa.tar.gz
twinkle-2eb954cb34fcb956070896101df4ba78272939fa.tar.lz
twinkle-2eb954cb34fcb956070896101df4ba78272939fa.tar.xz
twinkle-2eb954cb34fcb956070896101df4ba78272939fa.zip
Skip over the mutex field when copying t_call_info data
t_line::get_call_info() returns a copy of a (locked) t_call_info; copying the mutex, aside from being undefined in POSIX, returns an unexpectedly locked copy, possibly resulting in a deadlock. This fix is pretty much a copy of the one applied to t_call_record in 38bb6b7, with an added check for self-assignment. Like its predecessor, it is still susceptible to deadlock, though (as unlikely as it may be). Fixes #73
Diffstat (limited to 'src')
-rw-r--r--src/line.cpp38
-rw-r--r--src/line.h3
2 files changed, 40 insertions, 1 deletions
diff --git a/src/line.cpp b/src/line.cpp
index 1eb52b8..1ba5d96 100644
--- a/src/line.cpp
+++ b/src/line.cpp
@@ -38,6 +38,43 @@ t_call_info::t_call_info() {
clear();
}
+t_call_info::t_call_info(const t_call_info& that) {
+ *this = that;
+}
+
+t_call_info& t_call_info::operator=(const t_call_info& that) {
+ if (this != &that) {
+ // FIXME: This may deadlock if "a=b" and "b=a" are run in
+ // parallel. The proper solution would be to switch
+ // to std::mutex and call std::lock(this,that).
+ t_mutex_guard x1(that.mutex);
+ t_mutex_guard x2(this->mutex);
+
+ from_uri = that.from_uri;
+ from_display = that.from_display;
+
+ from_display_override = that.from_display_override;
+
+ from_organization = that.from_organization;
+ to_uri = that.to_uri;
+ to_display = that.to_display;
+ to_organization = that.to_organization;
+ subject = that.subject;
+ dtmf_supported = that.dtmf_supported;
+ dtmf_inband = that.dtmf_inband;
+ dtmf_info = that.dtmf_info;
+ hdr_referred_by = that.hdr_referred_by;
+
+ last_provisional_reason = that.last_provisional_reason;
+
+ send_codec = that.send_codec;
+ recv_codec = that.recv_codec;
+ refer_supported = that.refer_supported;
+ }
+
+ return *this;
+}
+
void t_call_info::clear(void) {
t_mutex_guard g(mutex);
@@ -2128,7 +2165,6 @@ void t_line::retry_retrieve_succeeded(void) {
}
t_call_info t_line::get_call_info(void) const {
- t_mutex_guard g(call_info.mutex);
return call_info;
}
diff --git a/src/line.h b/src/line.h
index adfa0e4..7b0788f 100644
--- a/src/line.h
+++ b/src/line.h
@@ -71,6 +71,9 @@ public:
bool refer_supported;
t_call_info();
+ t_call_info(const t_call_info&);
+ t_call_info& operator=(const t_call_info&);
+
void clear(void);
// Get the from display name to show to the user.