Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
jami-daemon
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
savoirfairelinux
jami-daemon
Commits
66d5d955
Commit
66d5d955
authored
3 years ago
by
Olivier Dion
Browse files
Options
Downloads
Patches
Plain Diff
agent: Fix possible race conditions
Change-Id: Ie6c21d1505f218a0de3bf79aec4565fc3713a922
parent
c6b84d39
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
test/agent/agent.cpp
+71
-36
71 additions, 36 deletions
test/agent/agent.cpp
with
71 additions
and
36 deletions
test/agent/agent.cpp
+
71
−
36
View file @
66d5d955
...
@@ -57,8 +57,9 @@ Agent::ping(const std::string& conversation)
...
@@ -57,8 +57,9 @@ Agent::ping(const std::string& conversation)
{
{
LOG_AGENT_STATE
();
LOG_AGENT_STATE
();
auto
cv
=
std
::
make_shared
<
std
::
condition_variable
>
();
std
::
mutex
mtx
;
auto
pongReceived
=
std
::
make_shared
<
std
::
atomic_bool
>
(
false
);
std
::
condition_variable
cv
;
std
::
atomic
<
bool
>
pongReceived
(
false
);
std
::
string
alphabet
=
"0123456789ABCDEF"
;
std
::
string
alphabet
=
"0123456789ABCDEF"
;
std
::
string
messageSent
;
std
::
string
messageSent
;
...
@@ -67,7 +68,7 @@ Agent::ping(const std::string& conversation)
...
@@ -67,7 +68,7 @@ Agent::ping(const std::string& conversation)
messageSent
.
push_back
(
alphabet
[
rand
()
%
alphabet
.
size
()]);
messageSent
.
push_back
(
alphabet
[
rand
()
%
alphabet
.
size
()]);
}
}
onMessageReceived_
.
add
([
=
](
const
std
::
string
&
/* accountID */
,
onMessageReceived_
.
add
([
&
](
const
std
::
string
&
/* accountID */
,
const
std
::
string
&
conversationID
,
const
std
::
string
&
conversationID
,
std
::
map
<
std
::
string
,
std
::
string
>
message
)
{
std
::
map
<
std
::
string
,
std
::
string
>
message
)
{
...
@@ -77,14 +78,15 @@ Agent::ping(const std::string& conversation)
...
@@ -77,14 +78,15 @@ Agent::ping(const std::string& conversation)
auto
msg
=
message
.
at
(
"body"
);
auto
msg
=
message
.
at
(
"body"
);
if
(
pongReceived
->
load
())
{
if
(
pongReceived
.
load
())
{
return
false
;
return
false
;
}
}
if
(
conversationID
==
conversation
and
message
.
at
(
"author"
)
!=
peerID_
if
(
conversationID
==
conversation
and
message
.
at
(
"author"
)
!=
peerID_
and
msg
==
"PONG:"
+
messageSent
)
{
and
msg
==
"PONG:"
+
messageSent
)
{
*
pongReceived
=
true
;
std
::
unique_lock
lk
(
mtx
);
cv
->
notify_one
();
pongReceived
.
store
(
true
);
cv
.
notify_one
();
return
false
;
return
false
;
}
}
...
@@ -97,11 +99,10 @@ Agent::ping(const std::string& conversation)
...
@@ -97,11 +99,10 @@ Agent::ping(const std::string& conversation)
/* Waiting for echo */
/* Waiting for echo */
std
::
mutex
mutex
;
std
::
unique_lock
<
std
::
mutex
>
lk
(
mtx
);
std
::
unique_lock
<
std
::
mutex
>
lck
(
mutex
);
bool
ret
=
std
::
cv_status
::
no_timeout
==
cv
->
wait_for
(
l
c
k
,
std
::
chrono
::
seconds
(
30
))
bool
ret
=
(
std
::
cv_status
::
no_timeout
==
cv
.
wait_for
(
lk
,
std
::
chrono
::
seconds
(
30
))
and
and
pongReceived
->
load
();
pongReceived
.
load
()
)
;
AGENT_INFO
(
"Pong %s"
,
ret
?
"received"
:
"missing"
);
AGENT_INFO
(
"Pong %s"
,
ret
?
"received"
:
"missing"
);
...
@@ -142,20 +143,19 @@ Agent::placeCall(const std::string& contact)
...
@@ -142,20 +143,19 @@ Agent::placeCall(const std::string& contact)
{
{
LOG_AGENT_STATE
();
LOG_AGENT_STATE
();
auto
cv
=
std
::
make_shared
<
std
::
condition_variable
>
();
std
::
mutex
mtx
;
std
::
condition_variable
cv
;
auto
callID
=
DRing
::
placeCall
(
accountID_
,
contact
);
bool
success
(
false
);
auto
success
=
std
::
make_shared
<
std
::
atomic
<
bool
>>
(
false
);
bool
over
(
false
);
auto
over
=
std
::
make_shared
<
std
::
atomic
<
bool
>>
(
false
);
if
(
callID
.
empty
())
{
std
::
string
callID
=
""
;
return
false
;
}
onCallStateChanged_
.
add
([
=
](
const
std
::
string
&
call_id
,
const
std
::
string
&
state
,
signed
code
)
{
onCallStateChanged_
.
add
([
&
](
const
std
::
string
&
call_id
,
const
std
::
string
&
state
,
signed
code
)
{
AGENT_INFO
(
"[call:%s] In state %s : %d"
,
callID
.
c_str
(),
state
.
c_str
(),
code
);
AGENT_INFO
(
"[call:%s] In state %s : %d"
,
callID
.
c_str
(),
state
.
c_str
(),
code
);
std
::
unique_lock
lk
(
mtx
);
if
(
call_id
!=
callID
)
{
if
(
call_id
!=
callID
)
{
return
true
;
return
true
;
}
}
...
@@ -163,39 +163,42 @@ Agent::placeCall(const std::string& contact)
...
@@ -163,39 +163,42 @@ Agent::placeCall(const std::string& contact)
bool
ret
=
true
;
bool
ret
=
true
;
if
(
"CURRENT"
==
state
)
{
if
(
"CURRENT"
==
state
)
{
success
->
store
(
true
)
;
success
=
true
;
}
else
if
(
"OVER"
==
state
)
{
}
else
if
(
"OVER"
==
state
)
{
over
->
store
(
true
)
;
over
=
true
;
ret
=
false
;
ret
=
false
;
}
}
cv
->
notify_one
();
cv
.
notify_one
();
return
ret
;
return
ret
;
});
});
std
::
mutex
mtx
;
callID
=
DRing
::
placeCall
(
accountID_
,
contact
);
std
::
unique_lock
<
std
::
mutex
>
lck
{
mtx
};
AGENT_INFO
(
"Waiting for call %s"
,
callID
.
c_str
());
AGENT_INFO
(
"Waiting for call %s"
,
callID
.
c_str
());
/* TODO - Parametize me */
/* TODO - Parametize me */
cv
->
wait_for
(
lck
,
std
::
chrono
::
seconds
(
30
),
[
=
]{
{
return
success
->
load
()
or
over
->
load
();
std
::
unique_lock
lk
(
mtx
);
cv
.
wait_for
(
lk
,
std
::
chrono
::
seconds
(
30
),
[
&
]{
return
success
or
over
;
});
});
}
if
(
success
->
load
()
)
{
if
(
success
)
{
AGENT_INFO
(
"[call:%s] to %s: SUCCESS"
,
callID
.
c_str
(),
contact
.
c_str
());
AGENT_INFO
(
"[call:%s] to %s: SUCCESS"
,
callID
.
c_str
(),
contact
.
c_str
());
DRing
::
hangUp
(
callID
);
DRing
::
hangUp
(
callID
);
}
else
{
}
else
{
AGENT_INFO
(
"[call:%s] to %s: FAIL"
,
callID
.
c_str
(),
contact
.
c_str
());
AGENT_INFO
(
"[call:%s] to %s: FAIL"
,
callID
.
c_str
(),
contact
.
c_str
());
}
}
if
(
not
over
->
load
())
{
if
(
not
over
)
{
cv
->
wait_for
(
lck
,
std
::
chrono
::
seconds
(
30
),
[
=
]
{
return
over
->
load
();
});
std
::
unique_lock
lk
(
mtx
);
cv
.
wait_for
(
lk
,
std
::
chrono
::
seconds
(
30
),
[
&
]
{
return
over
;
});
}
}
return
success
->
load
()
;
return
success
;
}
}
void
void
...
@@ -230,8 +233,37 @@ Agent::activate(bool state)
...
@@ -230,8 +233,37 @@ Agent::activate(bool state)
{
{
LOG_AGENT_STATE
();
LOG_AGENT_STATE
();
std
::
mutex
mtx
;
std
::
condition_variable
cv
;
bool
done
=
false
;
onVolatileDetailsChanged_
.
add
([
&
](
const
std
::
string
&
accountID
,
const
std
::
map
<
std
::
string
,
std
::
string
>&
details
)
{
if
(
accountID_
!=
accountID
)
{
return
true
;
}
AGENT_INFO
(
"Account is %s"
,
details
.
at
(
DRing
::
Account
::
VolatileProperties
::
ACTIVE
).
c_str
());
std
::
unique_lock
lk
(
mtx
);
done
=
true
;
cv
.
notify_one
();
return
false
;
});
DRing
::
setAccountActive
(
accountID_
,
state
);
DRing
::
setAccountActive
(
accountID_
,
state
);
std
::
unique_lock
lk
(
mtx
);
cv
.
wait_for
(
lk
,
std
::
chrono
::
seconds
(
10
),
[
&
]{
return
done
;
});
if
(
state
)
{
if
(
state
)
{
waitForAnnouncement
();
waitForAnnouncement
();
}
}
...
@@ -482,12 +514,11 @@ Agent::registerStaticCallbacks()
...
@@ -482,12 +514,11 @@ Agent::registerStaticCallbacks()
void
void
Agent
::
waitForAnnouncement
(
std
::
chrono
::
seconds
timeout
)
Agent
::
waitForAnnouncement
(
std
::
chrono
::
seconds
timeout
)
{
{
auto
cv
=
std
::
make_shared
<
std
::
condition_variable
>
()
;
std
::
condition_variable
cv
;
std
::
mutex
mtx
;
std
::
mutex
mtx
;
std
::
unique_lock
<
std
::
mutex
>
lk
{
mtx
};
onVolatileDetailsChanged_
.
add
([
=
](
const
std
::
string
&
accountID
,
onVolatileDetailsChanged_
.
add
([
&
](
const
std
::
string
&
accountID
,
const
std
::
map
<
std
::
string
,
std
::
string
>&
details
)
{
const
std
::
map
<
std
::
string
,
std
::
string
>&
details
)
{
if
(
accountID_
!=
accountID
)
{
if
(
accountID_
!=
accountID
)
{
...
@@ -503,12 +534,16 @@ Agent::waitForAnnouncement(std::chrono::seconds timeout)
...
@@ -503,12 +534,16 @@ Agent::waitForAnnouncement(std::chrono::seconds timeout)
return
true
;
return
true
;
}
}
cv
->
notify_one
();
std
::
unique_lock
lk
(
mtx
);
cv
.
notify_one
();
return
false
;
return
false
;
});
});
AGENT_ASSERT
(
std
::
cv_status
::
no_timeout
==
cv
->
wait_for
(
lk
,
timeout
),
std
::
unique_lock
lk
(
mtx
);
AGENT_ASSERT
(
std
::
cv_status
::
no_timeout
==
cv
.
wait_for
(
lk
,
timeout
),
"Timeout while waiting for account announcement on DHT"
);
"Timeout while waiting for account announcement on DHT"
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment