Skip to content

Commit 09837ad

Browse files
committed
Fix another deadlock.
1 parent f7d20f9 commit 09837ad

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

Common/Cpp/CancellableScope.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ void Cancellable::add_cancel_listener(CancelListener& listener){
3939
void Cancellable::remove_cancel_listener(CancelListener& listener){
4040
m_impl->m_listeners.remove(listener);
4141
}
42+
bool Cancellable::try_add_cancel_listener(CancelListener& listener){
43+
return m_impl->m_listeners.try_add(listener);
44+
}
4245

4346

4447
Cancellable::Cancellable()

Common/Cpp/CancellableScope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class Cancellable{
5252
void add_cancel_listener(CancelListener& listener);
5353
void remove_cancel_listener(CancelListener& listener);
5454

55+
bool try_add_cancel_listener(CancelListener& listener);
56+
5557

5658
public:
5759
virtual ~Cancellable();

SerialPrograms/Source/Controllers/SerialPABotBase/Connection/PABotBase.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,11 +952,26 @@ BotBaseMessage PABotBase::wait_for_request(uint64_t seqnum, Cancellable* cancell
952952
return ret;
953953
}
954954
}
955+
cv_wait(cancelled, lg);
956+
}
957+
}
958+
959+
960+
void PABotBase::cv_wait(Cancellable* cancellable, std::unique_lock<std::mutex>& lg){
961+
if (cancellable == nullptr){
955962
m_cv.wait(lg);
963+
return;
964+
}
965+
966+
// Only wait if we're able to attach the cancel listener.
967+
if (cancellable->try_add_cancel_listener(*this)){
968+
m_cv.wait(lg);
969+
cancellable->remove_cancel_listener(*this);
956970
}
957971
}
958972

959973

960974

961975

976+
962977
}

SerialPrograms/Source/Controllers/SerialPABotBase/Connection/PABotBase.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,7 @@ class PABotBase : public BotBaseController, private PABotBaseConnection{
176176
BotBaseMessage wait_for_request(uint64_t seqnum, Cancellable* cancelled = nullptr);
177177

178178
// Make we get notified of a cancellable cancels so we can wake up.
179-
void cv_wait(Cancellable* cancellable, std::unique_lock<std::mutex>& lg){
180-
if (cancellable){
181-
cancellable->add_cancel_listener(*this);
182-
}
183-
m_cv.wait(lg);
184-
if (cancellable){
185-
cancellable->remove_cancel_listener(*this);
186-
}
187-
}
179+
void cv_wait(Cancellable* cancellable, std::unique_lock<std::mutex>& lg);
188180

189181
private:
190182
Logger& m_logger;

SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_RecordKeyboardController.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,17 @@ std::string json_to_cpp(const JsonArray& history){
138138
ControllerState state;
139139
for (const JsonValue& command : history){
140140
const JsonObject& snapshot = command.to_object_throw();
141-
Milliseconds duration(snapshot.get_integer_throw("duration_in_ms"));
141+
142+
uint64_t duration = 0;
143+
bool ok = false;
144+
ok |= snapshot.read_integer(duration, "duration_in_ms");
145+
ok |= snapshot.read_integer(duration, "ms");
146+
if (!ok){
147+
throw JsonParseException("", "ms");
148+
}
149+
142150
state.load_json(snapshot);
143-
ret += state.to_cpp(duration, Milliseconds(0));
151+
ret += state.to_cpp(Milliseconds(duration), Milliseconds(0));
144152
}
145153
return ret;
146154
}
@@ -156,9 +164,17 @@ void execute_json_schedule(
156164
for (uint32_t i = 0; i < num_loops; i++){
157165
for (const JsonValue& command : history){
158166
const JsonObject& snapshot = command.to_object_throw();
159-
Milliseconds duration(snapshot.get_integer_throw("duration_in_ms"));
167+
168+
uint64_t duration = 0;
169+
bool ok = false;
170+
ok |= snapshot.read_integer(duration, "duration_in_ms");
171+
ok |= snapshot.read_integer(duration, "ms");
172+
if (!ok){
173+
throw JsonParseException("", "ms");
174+
}
175+
160176
state.load_json(snapshot);
161-
state.execute(context, context.controller(), duration);
177+
state.execute(context, context.controller(), Milliseconds(duration));
162178
}
163179
state.clear();
164180
state.execute(context, context.controller(), Seconds(seconds_wait_between_loops));

0 commit comments

Comments
 (0)