Skip to content

Commit 7327e7d

Browse files
committed
fix: fix the behavior of setTimeout
Currently `ios-device-lib` hangs when listing the installed applications on connected device. This happens when application is ran using sidekick. The applications are gathered from device on every 200ms. It seems that for some reasons, `ios-device-lib` is not able to create new `std::thread` and it hangs on `std::thread(operation)` on some windows machines. The result from listed applications is reported by chunks and a new `std::thread` is created for every reported chunk. As a workaround of this problem, we'll set timeout to `0` when listing the applications. (It was the default behavior before introducing `setTimeout` function). This PR also changes the interface of `setTimeout` and `clearTimeout` and makes them working with pointers instead of structs.
1 parent aef3881 commit 7327e7d

File tree

3 files changed

+23
-18
lines changed

3 files changed

+23
-18
lines changed

IOSDeviceLib/IOSDeviceLib.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ std::map<std::string, boost::any> receive_con_message(ConnectionMessageData data
659659
receive_con_message_mutex.lock();
660660

661661
ServiceConnRef conn = data.conn;
662-
TimeoutOutputData timeoutOutputData = setTimeout(data.timeout, &data, clean_con_resources);
662+
TimeoutOutputData* timeoutOutputData = setTimeout(data.timeout, &data, clean_con_resources);
663663

664664
std::map<std::string, boost::any> dict;
665665
char *buffer = new char[4];
@@ -673,12 +673,10 @@ std::map<std::string, boost::any> receive_con_message(ConnectionMessageData data
673673
if (bytes_read > 0)
674674
{
675675
Plist::readPlist(buffer, res, dict);
676-
clearTimeout(timeoutOutputData);
677676
}
678-
} else {
679-
clearTimeout(timeoutOutputData);
680677
}
681678

679+
clearTimeout(timeoutOutputData);
682680
delete[] buffer;
683681
receive_con_message_mutex.unlock();
684682
return dict;
@@ -1052,7 +1050,7 @@ void get_application_infos(std::string device_identifier, std::string method_id)
10521050
std::vector<json> livesync_app_infos;
10531051
while (true)
10541052
{
1055-
ConnectionMessageData connectionMessageData = { serviceInfo.connection, device_identifier, method_id, kInstallationProxy, 10 };
1053+
ConnectionMessageData connectionMessageData = { serviceInfo.connection, device_identifier, method_id, kInstallationProxy, 0 };
10561054
std::map<std::string, boost::any> dict = receive_con_message(connectionMessageData);
10571055
PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(dict.count(kErrorKey), boost::any_cast<std::string>(dict[kErrorKey]).c_str(), device_identifier, method_id);
10581056
if (dict.empty() || (dict.count(kStatusKey) && has_complete_status(dict)))

IOSDeviceLib/SetTimeout.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ DWORD WINAPI TimeoutThreadExecutor(LPVOID lpParam) {
88
TimeoutData* threadData = (TimeoutData*)lpParam;
99
std::this_thread::sleep_for(std::chrono::milliseconds(threadData->timeout * 1000));
1010
threadData->operation(threadData->data);
11-
free(threadData);
1211
return 0;
1312
}
1413
#endif
1514

16-
TimeoutOutputData setTimeout(int timeout, void * data, void(*operation)(void*)) {
15+
TimeoutOutputData* setTimeout(int timeout, void * data, void(*operation)(void*)) {
1716
std::thread::native_handle_type darwinHandle = nullptr;
1817
HANDLE windowsHandle = nullptr;
1918
struct TimeoutData* timeoutData = nullptr;
@@ -43,27 +42,35 @@ TimeoutOutputData setTimeout(int timeout, void * data, void(*operation)(void*))
4342
#endif
4443
}
4544

46-
return { darwinHandle, windowsHandle, timeoutData };
45+
TimeoutOutputData* result = reinterpret_cast<TimeoutOutputData*>(malloc(sizeof(struct TimeoutOutputData)));
46+
result->windowsHandle = windowsHandle;
47+
result->darwinHandle = darwinHandle;
48+
result->timeoutData = timeoutData;
49+
50+
return result;
4751
}
4852

49-
void clearTimeout(TimeoutOutputData data) {
50-
if (data.timeoutData) {
51-
free(data.timeoutData);
52-
data.timeoutData = nullptr;
53+
void clearTimeout(TimeoutOutputData* data) {
54+
if (data->timeoutData) {
55+
free(data->timeoutData);
56+
data->timeoutData = nullptr;
5357
}
5458

5559
#ifdef WIN32
56-
if (data.windowsHandle) {
57-
int terminateThreadResult = TerminateThread(data.windowsHandle, 9);
60+
if (data->windowsHandle) {
61+
int terminateThreadResult = TerminateThread(data->windowsHandle, 9);
5862
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminatethread#return-value
5963
if (terminateThreadResult == 0)
6064
{
6165
DWORD errorCode = GetLastError();
6266
}
6367
}
6468
#else
65-
if (data.darwinHandle) {
66-
pthread_cancel(data.darwinHandle);
69+
if (data->darwinHandle) {
70+
pthread_cancel(data->darwinHandle);
6771
}
6872
#endif
73+
74+
free(data);
75+
data = nullptr;
6976
}

IOSDeviceLib/SetTimeout.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ struct TimeoutOutputData {
3636
TimeoutData* timeoutData;
3737
};
3838

39-
TimeoutOutputData setTimeout(int timeout, void * data, void(*operation)(void*));
40-
void clearTimeout(TimeoutOutputData data);
39+
TimeoutOutputData* setTimeout(int timeout, void * data, void(*operation)(void*));
40+
void clearTimeout(TimeoutOutputData* data);

0 commit comments

Comments
 (0)