Skip to content

Commit 996c42b

Browse files
committed
Bit more proper closing sequence.
1 parent b351d89 commit 996c42b

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

src/ftdi/abstract-ftd2xx-win32.cc

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ static void asyncCallbackTrampoline(uv_async_t* handle) {
6767
device->asyncCallback();
6868
}
6969

70-
static void asyncCloseCallback(uv_handle_t* handle) {}
70+
static void asyncCloseCallbackTrampoline(uv_handle_t* handle) {
71+
PCSX::FTDI::Device* device = reinterpret_cast<PCSX::FTDI::Device*>(handle->data);
72+
device->asyncCloseCallback();
73+
}
7174

7275
PCSX::FTDI::Device::Device() {
7376
uv_async_init(s_gui->loop(), &m_async, asyncCallbackTrampoline);
@@ -79,7 +82,9 @@ PCSX::FTDI::Device::~Device() {
7982
assert(!m_private->m_event);
8083
assert(!m_private->m_handle);
8184
delete m_private;
82-
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), asyncCloseCallback);
85+
uv_loop_t* loop = m_async.loop;
86+
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), asyncCloseCallbackTrampoline);
87+
while (!m_asyncClosed) uv_run(loop, UV_RUN_ONCE);
8388
}
8489

8590
void PCSX::FTDI::Device::open() {
@@ -95,6 +100,10 @@ void PCSX::FTDI::Device::close() {
95100
SetEvent(s_kickEvent);
96101
}
97102
bool PCSX::FTDI::Device::isOpened() const { return m_private->m_state == Private::DeviceData::STATE_OPENED; }
103+
bool PCSX::FTDI::Device::isBusy() const {
104+
return m_private->m_state == Private::DeviceData::STATE_CLOSE_PENDING ||
105+
m_private->m_state == Private::DeviceData::STATE_OPEN_PENDING;
106+
}
98107

99108
void PCSX::FTDI::Devices::scan() {
100109
FT_STATUS status;
@@ -185,6 +194,7 @@ void PCSX::FTDI::Devices::threadProc() {
185194
if (!device) continue;
186195
DWORD events;
187196
FT_GetEventStatus(device->m_private->m_handle, &events);
197+
printf("%i", events);
188198
} while (idx != WAIT_OBJECT_0);
189199
}
190200
CloseHandle(s_kickEvent);
@@ -216,6 +226,31 @@ void PCSX::FTDI::Devices::stopThread() {
216226

217227
bool PCSX::FTDI::Devices::isThreadRunning() { return s_threadRunning; }
218228

229+
void PCSX::FTDI::Devices::shutdown() {
230+
if (!isThreadRunning()) startThread();
231+
{
232+
bool run = true;
233+
while (run) {
234+
run = false;
235+
std::unique_lock<std::shared_mutex> guard(s_listLock);
236+
for (unsigned i = 0; i < s_numDevs; i++) {
237+
auto& device = s_devices[i];
238+
switch (device.m_private->m_state) {
239+
case Private::DeviceData::STATE_OPENED:
240+
device.close();
241+
case Private::DeviceData::STATE_CLOSE_PENDING:
242+
case Private::DeviceData::STATE_OPEN_PENDING:
243+
run = true;
244+
break;
245+
}
246+
}
247+
}
248+
}
249+
stopThread();
250+
delete[] s_devices;
251+
s_numDevs = 0;
252+
}
253+
219254
void PCSX::FTDI::Devices::setGUI(GUI* gui) { s_gui = gui; }
220255

221256
#endif

src/ftdi/abstract.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ class Device {
4949
const std::string& getDescription() const { return m_description; }
5050

5151
bool isOpened() const;
52+
bool isBusy() const;
5253

5354
void open();
5455
void close();
5556

5657
// technically private, but difficult to enforce properly
5758
void asyncCallback() {}
59+
void asyncCloseCallback() { m_asyncClosed = true; }
5860

5961
private:
6062
bool m_locked = false;
@@ -72,6 +74,7 @@ class Device {
7274
std::atomic_uint16_t m_slicesIndexes = 0;
7375

7476
uv_async_t m_async;
77+
bool m_asyncClosed = false;
7578

7679
unsigned usedSlices() {
7780
uint16_t indexes = m_slicesIndexes.load();
@@ -96,6 +99,7 @@ class Device {
9699
class Devices {
97100
public:
98101
static void scan();
102+
static void shutdown();
99103
static void iterate(std::function<bool(Device&)>);
100104
static bool isThreadRunning();
101105
static void startThread();

src/gui/widgets/ftdi.cc

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,33 @@ void PCSX::Widgets::FTDI::draw(const char* title) {
4343

4444
ImGui::Text((std::to_string(count) + " devices detected").c_str());
4545
ImGui::Separator();
46-
::PCSX::FTDI::Devices::iterate([](::PCSX::FTDI::Device& d) {
46+
::PCSX::FTDI::Device* devToClose = nullptr;
47+
::PCSX::FTDI::Device* devToOpen = nullptr;
48+
::PCSX::FTDI::Devices::iterate([&](::PCSX::FTDI::Device& d) mutable {
4749
ImGui::Text("Vendor Id: %04x", d.getVendorID());
4850
ImGui::Text("Device Id: %04x", d.getDeviceID());
4951
ImGui::Text("Type: %i", d.getType());
5052
ImGui::Text("Serial: %s", d.getSerial().c_str());
5153
ImGui::Text("Description: %s", d.getDescription().c_str());
5254
ImGui::Text("Locked: %s", d.isLocked() ? "true" : "false");
5355
ImGui::Text("High Speed: %s", d.isHighSpeed() ? "true" : "false");
56+
ImGui::Text("Opened: %s", d.isOpened() ? "true" : "false");
57+
if (d.isOpened() && !d.isBusy()) {
58+
if (ImGui::Button("Close")) {
59+
devToClose = &d;
60+
}
61+
} else if (!d.isBusy()) {
62+
if (ImGui::Button("Open")) {
63+
devToOpen = &d;
64+
}
65+
} else {
66+
ImGui::Text("Device is busy");
67+
}
5468
ImGui::Separator();
5569
return true;
5670
});
57-
5871
ImGui::End();
72+
73+
if (devToClose) devToClose->close();
74+
if (devToOpen) devToOpen->open();
5975
}

src/main/main.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ int main(int argc, char **argv) {
227227
PCSX::g_emulator.m_gpu->shutdown();
228228
PCSX::g_emulator.m_cdrom->m_iso.shutdown();
229229

230+
PCSX::FTDI::Devices::shutdown();
231+
230232
s_gui->close();
231233

232234
delete s_gui;

0 commit comments

Comments
 (0)