diff options
author | Frédéric Brière <fbriere@fbriere.net> | 2016-10-03 11:29:00 -0400 |
---|---|---|
committer | Frédéric Brière <fbriere@fbriere.net> | 2016-10-04 17:55:27 -0400 |
commit | 2eb954cb34fcb956070896101df4ba78272939fa (patch) | |
tree | 33dc1a1d283f88d55f9dae36fa8a180e6da943e2 /src | |
parent | a06681c29a66b7213eef0261d689230ee7515e5e (diff) | |
download | twinkle-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.cpp | 38 | ||||
-rw-r--r-- | src/line.h | 3 |
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; } @@ -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. |