Skip to content

Commit c2ca504

Browse files
Merge pull request #302 from pwpiwi/fix_QtThreads
fixing the crash on exit (issue #284)
2 parents a4a6780 + 5acd195 commit c2ca504

7 files changed

+75
-49
lines changed

client/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
2020
LUALIB = ../liblua/liblua.a
2121
LDFLAGS = $(COMMON_FLAGS)
2222
CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O3
23-
CXXFLAGS = -Wall -O3
23+
CXXFLAGS = -I../include -Wall -O3
2424

2525
LUAPLATFORM = generic
2626
platform = $(shell uname)

client/proxgui.cpp

+28-10
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,22 @@
1010

1111
#include "proxgui.h"
1212
#include "proxguiqt.h"
13+
#include "proxmark3.h"
1314

1415
static ProxGuiQT *gui = NULL;
16+
static WorkerThread *main_loop_thread = NULL;
17+
18+
WorkerThread::WorkerThread(char *script_cmds_file, bool usb_present) : script_cmds_file(script_cmds_file), usb_present(usb_present)
19+
{
20+
}
21+
22+
WorkerThread::~WorkerThread()
23+
{
24+
}
25+
26+
void WorkerThread::run() {
27+
main_loop(script_cmds_file, usb_present);
28+
}
1529

1630
extern "C" void ShowGraphWindow(void)
1731
{
@@ -39,31 +53,35 @@ extern "C" void RepaintGraphWindow(void)
3953

4054
extern "C" void MainGraphics(void)
4155
{
42-
if (!gui)
43-
return;
56+
if (!gui)
57+
return;
4458

45-
gui->MainLoop();
59+
main_loop_thread->start();
60+
gui->MainLoop();
4661
}
4762

48-
extern "C" void InitGraphics(int argc, char **argv)
63+
extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, bool usb_present)
4964
{
5065
#ifdef Q_WS_X11
51-
bool useGUI = getenv("DISPLAY") != 0;
66+
bool useGUI = getenv("DISPLAY") != 0;
5267
#else
53-
bool useGUI = true;
68+
bool useGUI = true;
5469
#endif
55-
if (!useGUI)
56-
return;
70+
if (!useGUI)
71+
return;
5772

58-
gui = new ProxGuiQT(argc, argv);
73+
gui = new ProxGuiQT(argc, argv);
74+
main_loop_thread = new WorkerThread(script_cmds_file, usb_present);
75+
QObject::connect(main_loop_thread, SIGNAL(finished()), main_loop_thread, SLOT(deleteLater()));
76+
QObject::connect(main_loop_thread, SIGNAL(finished()), gui, SLOT(_Exit()));
5977
}
6078

79+
6180
extern "C" void ExitGraphics(void)
6281
{
6382
if (!gui)
6483
return;
6584

6685
gui->Exit();
67-
//delete gui;
6886
gui = NULL;
6987
}

client/proxgui.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void ShowGraphWindow(void);
1919
void HideGraphWindow(void);
2020
void RepaintGraphWindow(void);
2121
void MainGraphics(void);
22-
void InitGraphics(int argc, char **argv);
22+
void InitGraphics(int argc, char **argv, char *script_cmds_file, bool usb_present);
2323
void ExitGraphics(void);
2424

2525
#define MAX_GRAPH_TRACE_LEN (40000*8)

client/proxguiqt.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void ProxGuiQT::_HideGraphWindow(void)
8484
void ProxGuiQT::_Exit(void) {
8585
delete this;
8686
}
87+
8788
void ProxGuiQT::MainLoop()
8889
{
8990
plotapp = new QApplication(argc, argv);
@@ -110,7 +111,7 @@ ProxGuiQT::~ProxGuiQT(void)
110111
//}
111112
if (plotapp) {
112113
plotapp->quit();
113-
delete plotapp;
114+
// delete plotapp;
114115
plotapp = NULL;
115116
}
116117
}

client/proxguiqt.h

+13
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,17 @@ class ProxGuiQT : public QObject
118118
void HideGraphWindowSignal(void);
119119
void ExitSignal(void);
120120
};
121+
122+
123+
class WorkerThread : public QThread {
124+
Q_OBJECT;
125+
public:
126+
WorkerThread(char*, bool);
127+
~WorkerThread();
128+
void run();
129+
private:
130+
char *script_cmds_file = NULL;
131+
bool usb_present = false;
132+
};
133+
121134
#endif // PROXGUI_QT

client/proxmark3.c

+21-36
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ struct receiver_arg {
5757
int run;
5858
};
5959

60-
struct main_loop_arg {
61-
int usb_present;
62-
char *script_cmds_file;
63-
};
64-
6560
byte_t rx[0x1000000];
6661
byte_t* prx = rx;
6762

@@ -97,13 +92,13 @@ static void *uart_receiver(void *targ) {
9792
return NULL;
9893
}
9994

100-
static void *main_loop(void *targ) {
101-
struct main_loop_arg *arg = (struct main_loop_arg*)targ;
95+
96+
void main_loop(char *script_cmds_file, bool usb_present) {
10297
struct receiver_arg rarg;
10398
char *cmd = NULL;
10499
pthread_t reader_thread;
105100

106-
if (arg->usb_present == 1) {
101+
if (usb_present) {
107102
rarg.run = 1;
108103
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
109104
// cache Version information now:
@@ -113,10 +108,10 @@ static void *main_loop(void *targ) {
113108
FILE *script_file = NULL;
114109
char script_cmd_buf[256]; // iceman, needs lua script the same file_path_buffer as the rest
115110

116-
if (arg->script_cmds_file) {
117-
script_file = fopen(arg->script_cmds_file, "r");
111+
if (script_cmds_file) {
112+
script_file = fopen(script_cmds_file, "r");
118113
if (script_file) {
119-
printf("using 'scripting' commands file %s\n", arg->script_cmds_file);
114+
printf("using 'scripting' commands file %s\n", script_cmds_file);
120115
}
121116
}
122117

@@ -171,19 +166,16 @@ static void *main_loop(void *targ) {
171166

172167
write_history(".history");
173168

174-
if (arg->usb_present == 1) {
169+
if (usb_present) {
175170
rarg.run = 0;
176171
pthread_join(reader_thread, NULL);
177172
}
178173

179-
ExitGraphics();
180-
181174
if (script_file) {
182175
fclose(script_file);
183176
script_file = NULL;
184177
}
185-
pthread_exit(NULL);
186-
return NULL;
178+
187179
}
188180

189181
static void dumpAllHelp(int markdown)
@@ -224,6 +216,7 @@ static void set_my_executable_path(void)
224216
}
225217
}
226218

219+
227220
int main(int argc, char* argv[]) {
228221
srand(time(0));
229222

@@ -249,25 +242,20 @@ int main(int argc, char* argv[]) {
249242

250243
set_my_executable_path();
251244

252-
// Make sure to initialize
253-
struct main_loop_arg marg = {
254-
.usb_present = 0,
255-
.script_cmds_file = NULL
256-
};
257-
pthread_t main_loop_thread;
258-
245+
bool usb_present = false;
246+
char *script_cmds_file = NULL;
259247

260248
sp = uart_open(argv[1]);
261249
if (sp == INVALID_SERIAL_PORT) {
262250
printf("ERROR: invalid serial port\n");
263-
marg.usb_present = 0;
251+
usb_present = false;
264252
offline = 1;
265253
} else if (sp == CLAIMED_SERIAL_PORT) {
266254
printf("ERROR: serial port is claimed by another process\n");
267-
marg.usb_present = 0;
255+
usb_present = false;
268256
offline = 1;
269257
} else {
270-
marg.usb_present = 1;
258+
usb_present = true;
271259
offline = 0;
272260
}
273261

@@ -283,24 +271,21 @@ int main(int argc, char* argv[]) {
283271
flushAfterWrite = 1;
284272
}
285273
else
286-
marg.script_cmds_file = argv[2];
274+
script_cmds_file = argv[2];
287275
}
288276

289277
// create a mutex to avoid interlacing print commands from our different threads
290278
pthread_mutex_init(&print_lock, NULL);
291-
pthread_create(&main_loop_thread, NULL, &main_loop, &marg);
292279

293-
// build ui/graph forms on separate thread (killed on main_loop_thread);
294-
InitGraphics(argc, argv);
280+
#ifdef HAVE_GUI
281+
InitGraphics(argc, argv, script_cmds_file, usb_present);
295282
MainGraphics();
296-
//this won't return until ExitGraphics() is called
297-
298-
//wait for thread to finish
299-
pthread_join(main_loop_thread, NULL);
300-
283+
#else
284+
main_loop(script_cmds_file, usb_present);
285+
#endif
301286

302287
// Clean up the port
303-
if (offline == 0) {
288+
if (usb_present) {
304289
uart_close(sp);
305290
}
306291

client/proxmark3.h

+9
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,17 @@
1616

1717
#define PROXPROMPT "proxmark3> "
1818

19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
1923
void SendCommand(UsbCommand *c);
2024
const char *get_my_executable_path(void);
2125
const char *get_my_executable_directory(void);
26+
void main_loop(char *script_cmds_file, bool usb_present);
27+
28+
#ifdef __cplusplus
29+
}
30+
#endif
2231

2332
#endif

0 commit comments

Comments
 (0)