1 // ----------------------------------------------------------------------------
2 //	qrunner.cxx
3 //
4 // Copyright (C) 2007-2009
5 //		Stelios Bounanos, M0GLD
6 //
7 // This file is part of fldigi.
8 //
9 // fldigi is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // fldigi is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 // ----------------------------------------------------------------------------
22 
23 #include <config.h>
24 
25 #include <unistd.h>
26 #include <errno.h>
27 #if defined(__CYGWIN__)
28 #  include <sys/types.h>
29 #  include <sys/socket.h>
30 #elif defined(__MINGW32__)
31 #  include "compat.h"
32 #endif
33 #include <fcntl.h>
34 
35 #include <FL/Fl.H>
36 
37 #include "fqueue.h"
38 #include "qrunner.h"
39 
40 #ifndef __MINGW32__
41 #  define QRUNNER_EAGAIN() (errno == EAGAIN)
42 #else
43 #  define QRUNNER_EAGAIN() ((errno = WSAGetLastError()) == WSAEWOULDBLOCK)
44 #endif
45 // qrunner threads
46 const char *sztid[] = {
47 	"INVALID_TID",
48 	"TRX_TID",
49 	"TOD_TID",
50 	"QRZ_TID",
51 	"RIGCTL_TID",
52 	"NORIGCTL_TID",
53 	"EQSL_TID",
54 	"ADIF_RW_TID",
55 	"ADIF_MERGE_TID",
56 	"XMLRPC_TID",
57 	"ARQ_TID",
58 	"ARQSOCKET_TID",
59 	"MACLOGGER_TID",
60 	"KISS_TID",
61 	"KISSSOCKET_TID",
62 	"PSM_TID",
63 	"AUDIO_ALERT_TID",
64 	"FD_TID",
65 	"N3FJP_TID",
66 	"DXCC_TID",
67 	"WKEY_TID",
68 	"CWIO_TID",
69 	"FMT_TID"
70 	"FLMAIN_TID"
71 };
72 
qrunner_debug(int tid,const char * name)73 void qrunner_debug(int tid, const char *name)
74 {
75 	if (tid > ((int)sizeof(sztid)-1)) tid = 0;
76 	else tid++;
77 
78 	if (tid < 2) return;
79 
80 	FILE *fd = (FILE *)0;
81 	fd = fl_fopen("qrunner.txt", "a");
82 	if(fd) {
83 		fprintf(fd, "%s, %s\n", sztid[tid], name);
84 		fclose(fd);
85 	}
86 }
87 
qrunner()88 qrunner::qrunner() : attached(false), inprog(false), drop_flag(false)
89 {
90 	fifo = new fqueue(FIFO_SIZE);
91 #ifndef __WOE32__
92 	if (pipe(pfd) == -1)
93 #else
94 	if (socketpair(PF_INET, SOCK_STREAM, 0, pfd) == -1)
95 #endif
96 		throw qexception(errno);
97 	set_cloexec(pfd[0], 1);
98 	set_cloexec(pfd[1], 1);
99 	if (set_nonblock(pfd[0], 1) == -1)
100 		throw qexception(errno);
101 #ifdef __WOE32__
102 	set_nodelay(pfd[1], 1);
103 #endif
104 }
105 
~qrunner()106 qrunner::~qrunner()
107 {
108 	detach();
109 	close(pfd[0]);
110 	close(pfd[1]);
111 	delete fifo;
112 }
113 
attach(int id_no,std::string id_string)114 void qrunner::attach(int id_no, std::string id_string)
115 {
116 	Fl::add_fd(pfd[0], FL_READ, reinterpret_cast<Fl_FD_Handler>(qrunner::execute), this);
117 	attached = true;
118 	_id_no = id_no;
119 	_id_string.assign(id_string);
120 }
121 
attach(void)122 void qrunner::attach(void)
123 {
124 	Fl::add_fd(pfd[0], FL_READ, reinterpret_cast<Fl_FD_Handler>(qrunner::execute), this);
125 	attached = true;
126 }
detach(void)127 void qrunner::detach(void)
128 {
129 	attached = false;
130 	Fl::remove_fd(pfd[0], FL_READ);
131 }
132 
133 static unsigned char rbuf[FIFO_SIZE];
134 
execute(int fd,void * arg)135 void qrunner::execute(int fd, void *arg)
136 {
137 	qrunner *qr = reinterpret_cast<qrunner *>(arg);
138 
139 	if (qr->inprog)
140 		return;
141 
142 	qr->inprog = true;
143 
144 	long n = QRUNNER_READ(fd, rbuf, FIFO_SIZE);
145 	switch (n) {
146 	case -1:
147 		if (!QRUNNER_EAGAIN()) {
148 			throw qexception(errno);
149 		}
150 		// else fall through
151 	case 0:
152 		break;
153 	default:
154 		while (n--) {
155 			qr->fifo->execute();
156 		}
157 	}
158 
159 	qr->inprog = false;
160 }
161 
flush(void)162 void qrunner::flush(void)
163 {
164 	execute(pfd[0], this);
165 }
166