MythTV  master
mythsystemwindows.cpp
Go to the documentation of this file.
1 
2 // compat header
3 #include "compat.h"
4 
5 // Own header
6 #include "mythsystemlegacy.h"
7 #include "mythsystemwindows.h"
8 
9 // C++/C headers
10 #include <cerrno>
11 #include <csignal> // for kill()
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring>
15 #include <ctime>
16 #include <fcntl.h>
17 #include <unistd.h>
18 
19 // QT headers
20 #include <QCoreApplication>
21 #include <QMutex>
22 #include <QMap>
23 #include <QString>
24 #include <QStringList>
25 
26 // libmythbase headers
27 #include "mythcorecontext.h"
28 #include "mythlogging.h"
29 #include "mythevent.h"
30 #include "exitcodes.h"
31 
32 // Windows headers
33 #include <windows.h>
34 #include <tchar.h>
35 
36 #define CLOSE(x) \
37 if( (x) ) { \
38  CloseHandle((x)); \
39  fdLock.lock(); \
40  delete fdMap.value((x)); \
41  fdMap.remove((x)); \
42  fdLock.unlock(); \
43  (x) = nullptr; \
44 }
45 
46 struct FDType_t
47 {
49  int type;
50 };
51 using FDMap_t = QMap<HANDLE, FDType_t*>;
52 
53 /**********************************
54  * MythSystemLegacyManager method defines
55  *********************************/
56 static bool run_system = true;
57 static MythSystemLegacyManager *manager = nullptr;
62 static QMutex listLock;
63 static FDMap_t fdMap;
64 static QMutex fdLock;
65 
67 {
68  run_system = false;
69  if (manager)
70  manager->wait();
71  if (smanager)
72  smanager->wait();
73  if (readThread)
74  readThread->wait();
75  if (writeThread)
76  writeThread->wait();
77 }
78 
80  MThread(QString("SystemIOHandler%1").arg(read ? "R" : "W")),
81  m_pWaitLock(), m_pWait(), m_pLock(), m_pMap(PMap_t()),
82  m_read(read)
83 {
84  m_readbuf[0] = '\0';
85 }
86 
88 {
89  RunProlog();
90 
91  LOG(VB_GENERAL, LOG_INFO, QString("Starting IO manager (%1)")
92  .arg(m_read ? "read" : "write"));
93 
94  while( run_system )
95  {
96  {
97  QMutexLocker locker(&m_pWaitLock);
98  m_pWait.wait(&m_pWaitLock);
99  }
100 
101  while( run_system )
102  {
103  usleep(10ms); // ~100x per second, for ~3MBps throughput
104  m_pLock.lock();
105  if( m_pMap.isEmpty() )
106  {
107  m_pLock.unlock();
108  break;
109  }
110 
111  bool datafound = true;
112  m_pLock.unlock();
113 
114  while ( datafound && run_system )
115  {
116  m_pLock.lock();
117 
118  datafound = false;
119  PMap_t::iterator i, next;
120  for( i = m_pMap.begin(); i != m_pMap.end(); i = next )
121  {
122  next = i + 1;
123 
124  if( m_read )
125  datafound |= HandleRead(i.key(), i.value());
126  else
127  datafound |= HandleWrite(i.key(), i.value());
128  }
129  m_pLock.unlock();
130  }
131  }
132  }
133  RunEpilog();
134 }
135 
136 bool MythSystemLegacyIOHandler::HandleRead(HANDLE h, QBuffer *buff)
137 {
138  DWORD lenAvail;
139 
140  if ( !PeekNamedPipe( h, nullptr, 0, nullptr, &lenAvail, nullptr) )
141  return false;
142 
143  if ( lenAvail > 65536 )
144  lenAvail = 65536;
145 
146  DWORD lenRead;
147 
148  if ( !ReadFile( h, &m_readbuf, lenAvail, &lenRead, nullptr ) || lenRead == 0 )
149  {
150  m_pMap.remove(h);
151  return false;
152  }
153 
154  buff->buffer().append(m_readbuf, lenRead);
155 
156  // Get the corresponding MythSystemLegacy instance, and the stdout/stderr
157  // type
158  fdLock.lock();
159  FDType_t *fdType = fdMap.value(h);
160  fdLock.unlock();
161 
162  // Emit the data ready signal (1 = stdout, 2 = stderr)
163  MythSystemLegacyWindows *ms = fdType->ms;
164  emit ms->readDataReady(fdType->type);
165 
166  return true;
167 }
168 
169 bool MythSystemLegacyIOHandler::HandleWrite(HANDLE h, QBuffer *buff)
170 {
171  if( buff->atEnd() )
172  {
173  m_pMap.remove(h);
174  return false;
175  }
176 
177  int pos = buff->pos();
178  DWORD len = buff->size() - pos;
179  DWORD rlen;
180  len = (len > 32768 ? 32768 : len);
181 
182  if( !WriteFile(h, buff->read(len).constData(), len, &rlen, nullptr) )
183  {
184  m_pMap.remove(h);
185  return false;
186  }
187 
188  if( rlen != len )
189  buff->seek(pos+rlen);
190 
191  return true;
192 }
193 
194 void MythSystemLegacyIOHandler::insert(HANDLE h, QBuffer *buff)
195 {
196  m_pLock.lock();
197  m_pMap.insert(h, buff);
198  m_pLock.unlock();
199  wake();
200 }
201 
203 {
204  QMutexLocker locker(&m_pLock);
205  while (m_pMap.contains(h))
206  {
207  locker.unlock();
208  usleep(10ms);
209  locker.relock();
210  }
211 }
212 
214 {
215  m_pLock.lock();
216  if (m_read)
217  {
218  PMap_t::iterator i;
219  i = m_pMap.find(h);
220  HandleRead(i.key(), i.value());
221  }
222  m_pMap.remove(h);
223  m_pLock.unlock();
224 }
225 
227 {
228  QMutexLocker locker(&m_pWaitLock);
229  m_pWait.wakeAll();
230 }
231 
232 
234 {
235  if (m_children)
236  free( m_children );
237  wait();
238 }
239 
241 {
242  RunProlog();
243 
244  LOG(VB_GENERAL, LOG_INFO, "Starting process manager");
245 
246  // run_system is set to false during shutdown, and we need this thread to
247  // exit during shutdown.
248  while( run_system )
249  {
250  // check for any running processes
251  m_mapLock.lock();
252 
253  if( m_childCount == 0 )
254  {
255  m_mapLock.unlock();
256  usleep( 100ms );
257  continue;
258  }
259 
260  DWORD result = WaitForMultipleObjects( m_childCount, m_children,
261  FALSE, 100 );
262 
263  if ( result == WAIT_TIMEOUT || result == WAIT_FAILED )
264  {
265  m_mapLock.unlock();
266  continue;
267  }
268 
269  int index = result - WAIT_OBJECT_0;
270  if ( index < 0 || index > m_childCount - 1 )
271  {
272  m_mapLock.unlock();
273  continue;
274  }
275  HANDLE child = m_children[index];
276 
277  // pop exited process off managed list, add to cleanup list
278  MythSystemLegacyWindows *ms = m_pMap.take(child);
280  m_mapLock.unlock();
281 
282  // Occasionally, the caller has deleted the structure from under
283  // our feet. If so, just log and move on.
284  if (!ms || !ms->m_parent)
285  {
286  LOG(VB_SYSTEM, LOG_ERR,
287  QString("Structure for child handle %1 already deleted!")
288  .arg((long long)child));
289  if (ms)
290  {
291  listLock.lock();
292  msList.append(ms);
293  listLock.unlock();
294  }
295  continue;
296  }
297 
298  listLock.lock();
299  msList.append(ms);
300 
301  DWORD status;
302  GetExitCodeProcess( child, &status );
303 
304  ms->SetStatus(status);
305  LOG(VB_SYSTEM, LOG_INFO,
306  QString("Managed child (Handle: %1) has exited! "
307  "command=%2, status=%3, result=%4")
308  .arg((long long)child) .arg(ms->GetLogCmd()) .arg(status)
309  .arg(ms->GetStatus()));
310 
311  // loop through running processes for any that require action
312  MSMap_t::iterator i;
313  auto now = SystemClock::now();
314 
315  m_mapLock.lock();
316  m_jumpLock.lock();
317  for (i = m_pMap.begin(); i != m_pMap.end(); ++i)
318  {
319  child = i.key();
320  ms = i.value();
321 
322  // handle processes beyond marked timeout
323  if( ms->m_timeout.time_since_epoch() > 0s && ms->m_timeout < now )
324  {
325  // issuing KILL signal after TERM failed in a timely manner
326  if( ms->GetStatus() == GENERIC_EXIT_TIMEOUT )
327  {
328  LOG(VB_SYSTEM, LOG_INFO,
329  QString("Managed child (Handle: %1) timed out, "
330  "issuing KILL signal").arg((long long)child));
331  // Prevent constant attempts to kill an obstinate child
332  ms->m_timeout = SystemTime(0s);
333  ms->Signal(SIGKILL);
334  }
335 
336  // issuing TERM signal
337  else
338  {
339  LOG(VB_SYSTEM, LOG_INFO,
340  QString("Managed child (Handle: %1) timed out"
341  ", issuing TERM signal").arg((long long)child));
343  ms->m_timeout = now + 1s;
344  ms->Term();
345  }
346  }
347 
348  if ( m_jumpAbort && ms->GetSetting("AbortOnJump") )
349  ms->Term();
350  }
351 
352  m_jumpAbort = false;
353  m_jumpLock.unlock();
354 
355  m_mapLock.unlock();
356 
357  // hold off unlocking until all the way down here to
358  // give the buffer handling a chance to run before
359  // being closed down by signal thread
360  listLock.unlock();
361  }
362 
363  // kick to allow them to close themselves cleanly
364  readThread->wake();
365  writeThread->wake();
366 
367  RunEpilog();
368 }
369 
370 // NOTE: This is only to be run while m_mapLock is locked!!!
372 {
373  int oldCount;
374 
375  oldCount = m_childCount;
376  m_childCount = m_pMap.size();
377 
378  MSMap_t::iterator i;
379  int j;
380  HANDLE child;
381 
382  if ( oldCount != m_childCount )
383  {
384  HANDLE *new_children;
385  new_children = (HANDLE *)realloc(m_children,
386  m_childCount * sizeof(HANDLE));
387  if (!new_children && m_childCount)
388  {
389  LOG(VB_SYSTEM, LOG_CRIT, "No memory to allocate new children");
390  free(m_children);
391  m_children = nullptr;
392  return;
393  }
394 
395  m_children = new_children;
396  }
397 
398  for (i = m_pMap.begin(), j = 0; i != m_pMap.end(); ++i)
399  {
400  child = i.key();
401  m_children[j++] = child;
402  }
403 }
404 
406 {
407  m_mapLock.lock();
408  ms->IncrRef();
409  m_pMap.insert(ms->m_child, ms);
411  m_mapLock.unlock();
412 
413  if (ms->m_stdpipe[0])
414  {
415  QByteArray ba = ms->GetBuffer(0)->data();
416  QBuffer wtb(&ba);
417  wtb.open(QIODevice::ReadOnly);
418  writeThread->insert(ms->m_stdpipe[0], &wtb);
419  writeThread->Wait(ms->m_stdpipe[0]);
420  writeThread->remove(ms->m_stdpipe[0]);
421  CLOSE(ms->m_stdpipe[0]);
422  }
423 
424  if( ms->GetSetting("UseStdout") )
425  {
426  FDType_t *fdType = new FDType_t;
427  fdType->ms = ms;
428  fdType->type = 1;
429  fdLock.lock();
430  fdMap.insert( ms->m_stdpipe[1], fdType );
431  fdLock.unlock();
432  readThread->insert(ms->m_stdpipe[1], ms->GetBuffer(1));
433  }
434 
435  if( ms->GetSetting("UseStderr") )
436  {
437  FDType_t *fdType = new FDType_t;
438  fdType->ms = ms;
439  fdType->type = 2;
440  fdLock.lock();
441  fdMap.insert( ms->m_stdpipe[2], fdType );
442  fdLock.unlock();
443  readThread->insert(ms->m_stdpipe[2], ms->GetBuffer(2));
444  }
445 }
446 
448 {
449  m_jumpLock.lock();
450  m_jumpAbort = true;
451  m_jumpLock.unlock();
452 }
453 
454 // spawn separate thread for signals to prevent manager
456 {
457  RunProlog();
458 
459  LOG(VB_GENERAL, LOG_INFO, "Starting process signal handler");
460  while( run_system )
461  {
462  usleep(50ms);
463  while( run_system )
464  {
465  // handle cleanup and signalling for closed processes
466  listLock.lock();
467  if( msList.isEmpty() )
468  {
469  listLock.unlock();
470  break;
471  }
472  MythSystemLegacyWindows *ms = msList.takeFirst();
473  listLock.unlock();
474 
475  if (!ms)
476  continue;
477 
478  if (ms->m_parent)
479  {
480  ms->m_parent->HandlePostRun();
481  }
482 
483  if (ms->m_stdpipe[0])
484  writeThread->remove(ms->m_stdpipe[0]);
485  CLOSE(ms->m_stdpipe[0]);
486 
487  if (ms->m_stdpipe[1])
488  readThread->remove(ms->m_stdpipe[1]);
489  CLOSE(ms->m_stdpipe[1]);
490 
491  if (ms->m_stdpipe[2])
492  readThread->remove(ms->m_stdpipe[2]);
493  CLOSE(ms->m_stdpipe[2]);
494 
495  if (ms->m_parent)
496  {
497  if( ms->GetStatus() == GENERIC_EXIT_OK )
498  emit ms->finished();
499  else
500  emit ms->error(ms->GetStatus());
501 
502  ms->disconnect();
503  ms->Unlock();
504  }
505 
506  ms->DecrRef();
507  }
508  }
509 
510  RunEpilog();
511 }
512 
513 /*******************************
514  * MythSystemLegacy method defines
515  ******************************/
516 
518  MythSystemLegacyPrivate("MythSystemLegacyWindows")
519 {
520  m_parent = parent;
521 
522  m_stdpipe[0] = nullptr;
523  m_stdpipe[1] = nullptr;
524  m_stdpipe[2] = nullptr;
525 
531 
532  // Start the threads if they haven't been started yet.
533  if (manager == nullptr)
534  {
536  manager->start();
537  }
538 
539  if (smanager == nullptr)
540  {
542  smanager->start();
543  }
544 
545  if (readThread == nullptr)
546  {
548  readThread->start();
549  }
550 
551  if (writeThread == nullptr)
552  {
554  writeThread->start();
555  }
556 }
557 
558 bool MythSystemLegacyWindows::ParseShell(const QString&, QString &, QStringList&)
559 {
560  return false;
561 }
562 
564 {
565  if( (GetStatus() != GENERIC_EXIT_RUNNING) || (!m_child) )
566  return;
567 
568  Signal(SIGTERM);
569  if( force )
570  {
571  // send KILL if it does not exit within one second
572  if( m_parent->Wait(1s) == GENERIC_EXIT_RUNNING )
573  Signal(SIGKILL);
574  }
575 }
576 
578 {
579  if( (GetStatus() != GENERIC_EXIT_RUNNING) || (!m_child) )
580  return;
581  LOG(VB_SYSTEM, LOG_INFO, QString("Child Handle %1 killed with %2")
582  .arg((long long)m_child).arg(sig));
583  TerminateProcess( m_child, sig * 256 );
584 }
585 
586 
587 #define MAX_BUFLEN 1024
588 void MythSystemLegacyWindows::Fork(std::chrono::seconds timeout)
589 {
590  BOOL bInherit = FALSE;
591 
592  QString LOC_ERR = QString("myth_system('%1'): Error: ").arg(GetLogCmd());
593 
594  LOG(VB_SYSTEM, LOG_DEBUG, QString("Launching: %1").arg(GetLogCmd()));
595 
596  HANDLE p_stdin[2] = { nullptr, nullptr };
597  HANDLE p_stdout[2] = { nullptr, nullptr };
598  HANDLE p_stderr[2] = { nullptr, nullptr };
599 
600  SECURITY_ATTRIBUTES saAttr;
601  STARTUPINFO si;
602 
603  ZeroMemory(&si, sizeof(STARTUPINFO));
604  si.cb = sizeof(STARTUPINFO);
605 
606  // Set the bInheritHandle flag so pipe handles are inherited.
607  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
608  saAttr.bInheritHandle = true;
609  saAttr.lpSecurityDescriptor = nullptr;
610 
611  /* set up pipes */
612  if( GetSetting("UseStdin") )
613  {
614  bInherit = TRUE;
615 
616  if (!CreatePipe(&p_stdin[0], &p_stdin[1], &saAttr, 0))
617  {
618  LOG(VB_GENERAL, LOG_ERR, LOC_ERR + "stdin pipe() failed");
620  }
621  else
622  {
623  // Ensure the write handle to the pipe for STDIN is not inherited.
624  if (!SetHandleInformation(p_stdin[1], HANDLE_FLAG_INHERIT, 0))
625  {
626  LOG(VB_SYSTEM, LOG_ERR, LOC_ERR + "stdin inheritance error");
628  }
629  else
630  {
631  si.hStdInput = p_stdin[0];
632  si.dwFlags |= STARTF_USESTDHANDLES;
633  }
634  }
635  }
636 
637  if( GetSetting("UseStdout") )
638  {
639  bInherit = TRUE;
640 
641  if (!CreatePipe(&p_stdout[0], &p_stdout[1], &saAttr, 0))
642  {
643  LOG(VB_SYSTEM, LOG_ERR, LOC_ERR + "stdout pipe() failed");
645  }
646  else
647  {
648  // Ensure the read handle to the pipe for STDOUT is not inherited.
649  if (!SetHandleInformation(p_stdout[0], HANDLE_FLAG_INHERIT, 0))
650  {
651  LOG(VB_SYSTEM, LOG_ERR, LOC_ERR + "stdout inheritance error");
653  }
654  else
655  {
656  si.hStdOutput = p_stdout[1];
657  si.dwFlags |= STARTF_USESTDHANDLES;
658  }
659  }
660  }
661 
662  if( GetSetting("UseStderr") )
663  {
664  bInherit = TRUE;
665 
666  if (!CreatePipe(&p_stderr[0], &p_stderr[1], &saAttr, 0))
667  {
668  LOG(VB_SYSTEM, LOG_ERR, LOC_ERR + "stderr pipe() failed");
670  }
671  else
672  {
673  // Ensure the read handle to the pipe for STDERR is not inherited.
674  if (!SetHandleInformation(p_stderr[0], HANDLE_FLAG_INHERIT, 0))
675  {
676  LOG(VB_SYSTEM, LOG_ERR, LOC_ERR + "stderr inheritance error");
678  }
679  else
680  {
681  si.hStdError = p_stderr[1];
682  si.dwFlags |= STARTF_USESTDHANDLES;
683  }
684  }
685  }
686 
687  // set up command args
688  QString cmd = GetCommand() + " " + GetArgs().join(" ");
689 
690  if (GetSetting("UseShell"))
691  cmd.prepend("cmd.exe /c ");
692 
693  SetCommand( cmd );
694 
695  QString sCmd = GetCommand();
696 
697  QString dir = GetDirectory();
698 
699  PROCESS_INFORMATION pi;
700  ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
701 
702  m_timeout = (timeout != 0s)
703  ? SystemClock::now() + timeout
704  : SystemClock::time_point();
705 
706  LPCWSTR pDir = nullptr;
707  if (dir.length() > 0)
708  pDir = (LPCWSTR)dir.utf16();
709 
710  char sCmdChar[256];
711  sprintf(sCmdChar, "%ls", (LPWSTR)sCmd.utf16() );
712 
713  char pDirChar[256];
714  sprintf(pDirChar, "%ls", pDir);
715 
716  bool success = CreateProcess( nullptr,
717  sCmdChar, // command line
718  nullptr, // process security attributes
719  nullptr, // primary thread security attributes
720  bInherit, // handles are inherited
721  0, // creation flags
722  nullptr, // use parent's environment
723  pDirChar, // use parent's current directory
724  &si, // STARTUPINFO pointer
725  &pi); // receives PROCESS_INFORMATION
726 
727  if (!success)
728  {
729  DWORD dwErr = GetLastError();
730  LOG(VB_SYSTEM, LOG_ERR,
731  QString( "%1 CreateProcess() failed (%2)")
732  .arg( LOC_ERR )
733  .arg( dwErr ));
735  }
736  else
737  {
738  /* parent */
739  m_child = pi.hProcess;
741 
742  LOG(VB_SYSTEM, LOG_INFO,
743  QString("Managed child (Handle: %1) has started! "
744  "%2%3 command=%4, timeout=%5")
745  .arg((long long)m_child)
746  .arg(GetSetting("UseShell") ? "*" : "")
747  .arg(GetSetting("RunInBackground") ? "&" : "")
748  .arg(GetLogCmd()).arg(timeout.count()));
749 
750  /* close unused pipe ends */
751  CLOSE(p_stdin[0]);
752  CLOSE(p_stdout[1]);
753  CLOSE(p_stderr[1]);
754 
755  // store the rest
756  m_stdpipe[0] = p_stdin[1];
757  m_stdpipe[1] = p_stdout[0];
758  m_stdpipe[2] = p_stderr[0];
759 
760  }
761 
762  /* Parent */
764  {
765  CLOSE(p_stdin[0]);
766  CLOSE(p_stdin[1]);
767  CLOSE(p_stdout[0]);
768  CLOSE(p_stdout[1]);
769  CLOSE(p_stderr[0]);
770  CLOSE(p_stderr[1]);
771  }
772 }
773 
775 {
776  if( manager == nullptr )
777  {
779  manager->start();
780  }
781  manager->append(this);
782 }
783 
785 {
786  if( manager == nullptr )
787  {
789  manager->start();
790  }
791  manager->jumpAbort();
792 }
793 
794 /*
795  * vim:ts=4:sw=4:ai:et:si:sts=4
796  */
fdMap
static FDMap_t fdMap
Definition: mythsystemwindows.cpp:63
mythevent.h
MythSystemLegacyIOHandler::Wait
void Wait(int fd)
Definition: mythsystemunix.cpp:225
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:283
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
MythSystemLegacyIOHandler::m_pLock
QMutex m_pLock
Definition: mythsystemunix.h:53
MythSystemLegacyManager::m_pMap
MSMap_t m_pMap
Definition: mythsystemunix.h:74
MythSystemLegacyManager
Definition: mythsystemunix.h:64
fdLock
static QMutex fdLock
Definition: mythsystemwindows.cpp:64
MythSystemLegacyWindows::MythSystemLegacyManager
friend class MythSystemLegacyManager
Definition: mythsystemwindows.h:105
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
MythSystemLegacy
Definition: mythsystemlegacy.h:67
MythSystemLegacyManager::m_mapLock
QMutex m_mapLock
Definition: mythsystemunix.h:75
MythSystemLegacyPrivate::SetCommand
void SetCommand(const QString &cmd)
Definition: mythsystemprivate.h:55
MythSystemLegacyPrivate
-*- Mode: c++ -*-
Definition: mythsystemprivate.h:21
MythSystemLegacyManager::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: mythsystemunix.cpp:271
GENERIC_EXIT_TIMEOUT
@ GENERIC_EXIT_TIMEOUT
Process timed out.
Definition: exitcodes.h:25
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:300
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
MythSystemLegacyPrivate::finished
void finished(void)
ShutdownMythSystemLegacy
void ShutdownMythSystemLegacy(void)
Definition: mythsystemwindows.cpp:66
SystemTime
std::chrono::time_point< SystemClock > SystemTime
Definition: mythchrono.h:67
MythSystemLegacyPrivate::SetStatus
void SetStatus(uint status)
Definition: mythsystemprivate.h:43
manager
static MythSystemLegacyManager * manager
Definition: mythsystemwindows.cpp:57
MThread::usleep
static void usleep(std::chrono::microseconds time)
Definition: mthread.cpp:335
MythSystemLegacy::finished
void finished(void)
MythSystemLegacyWindows::Signal
void Signal(int sig) override
Definition: mythsystemwindows.cpp:577
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:196
force
bool force
Definition: mythcommflag.cpp:70
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
CLOSE
#define CLOSE(x)
Definition: mythsystemwindows.cpp:36
MythSystemLegacyWindows::MythSystemLegacyIOHandler
friend class MythSystemLegacyIOHandler
Definition: mythsystemwindows.h:107
MythSystemLegacySignalManager::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: mythsystemunix.cpp:497
mythsystemlegacy.h
msList
static MSList_t msList
Definition: mythsystemwindows.cpp:61
FDType_t::ms
MythSystemLegacyWindows * ms
Definition: mythsystemwindows.cpp:48
PMap_t
QMap< int, QBuffer * > PMap_t
Definition: mythsystemunix.h:29
mythlogging.h
MythSystemLegacyManager::m_children
HANDLE * m_children
Definition: mythsystemwindows.h:66
MythSystemLegacyWindows::MythSystemLegacySignalManager
friend class MythSystemLegacySignalManager
Definition: mythsystemwindows.h:106
MythSystemLegacyWindows::Fork
void Fork(std::chrono::seconds timeout) override
Definition: mythsystemwindows.cpp:588
readThread
static MythSystemLegacyIOHandler * readThread
Definition: mythsystemwindows.cpp:59
MythSystemLegacyIOHandler
Definition: mythsystemunix.h:32
MSList_t
QList< QPointer< MythSystemLegacyUnix > > MSList_t
Definition: mythsystemunix.h:30
MythSystemLegacyPrivate::started
void started(void)
MythSystemLegacy::error
void error(uint status)
MythSystemLegacy::readDataReady
void readDataReady(int fd)
MythSystemLegacyManager::jumpAbort
void jumpAbort(void)
Definition: mythsystemunix.cpp:490
compat.h
MythSystemLegacyManager::m_jumpLock
QMutex m_jumpLock
Definition: mythsystemunix.h:77
MythSystemLegacyPrivate::GetLogCmd
QString & GetLogCmd(void)
Definition: mythsystemprivate.h:46
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:209
MythSystemLegacyManager::m_childCount
int m_childCount
Definition: mythsystemwindows.h:65
MythSystemLegacyPrivate::Unlock
void Unlock(void)
Definition: mythsystemprivate.h:68
MythSystemLegacyIOHandler::MythSystemLegacyIOHandler
MythSystemLegacyIOHandler(bool read)
Definition: mythsystemunix.h:35
MythSystemLegacyWindows::m_child
HANDLE m_child
Definition: mythsystemwindows.h:110
MythSystemLegacyManager::~MythSystemLegacyManager
~MythSystemLegacyManager() override
Definition: mythsystemunix.h:69
GENERIC_EXIT_NOT_OK
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:12
MythSystemLegacyWindows::JumpAbort
void JumpAbort(void) override
Definition: mythsystemwindows.cpp:784
MythSystemLegacyWindows::m_stdpipe
HANDLE m_stdpipe[3]
Definition: mythsystemwindows.h:113
MythSystemLegacyIOHandler::HandleWrite
void HandleWrite(int fd, QBuffer *buff)
Definition: mythsystemunix.cpp:188
MythSystemLegacyPrivate::readDataReady
void readDataReady(int fd)
SIGKILL
#define SIGKILL
Definition: compat.h:136
MythSystemLegacy::started
void started(void)
MythSystemLegacyWindows::ParseShell
bool ParseShell(const QString &cmd, QString &abscmd, QStringList &args) override
Definition: mythsystemwindows.cpp:558
listLock
static QMutex listLock
Definition: mythsystemwindows.cpp:62
MythSystemLegacyPrivate::GetArgs
QStringList & GetArgs(void)
Definition: mythsystemprivate.h:59
FDType_t
Definition: mythsystemunix.cpp:43
MythSystemLegacySignalManager
Definition: mythsystemunix.h:81
writeThread
static MythSystemLegacyIOHandler * writeThread
Definition: mythsystemwindows.cpp:60
MythSystemLegacyIOHandler::m_read
bool m_read
Definition: mythsystemunix.h:58
MythSystemLegacyManager::append
void append(MythSystemLegacyUnix *ms)
Definition: mythsystemunix.cpp:448
MythSystemLegacyIOHandler::remove
void remove(int fd)
Definition: mythsystemunix.cpp:236
MythSystemLegacyPrivate::GetSetting
bool GetSetting(const char *setting)
Definition: mythsystemprivate.h:50
mythsystemwindows.h
MythSystemLegacyIOHandler::m_pWait
QWaitCondition m_pWait
Definition: mythsystemunix.h:52
MythSystemLegacyWindows::Manage
void Manage(void) override
Definition: mythsystemwindows.cpp:774
mythcorecontext.h
smanager
static MythSystemLegacySignalManager * smanager
Definition: mythsystemwindows.cpp:58
MythSystemLegacyPrivate::GetBuffer
QBuffer * GetBuffer(int index)
Definition: mythsystemprivate.h:65
MythSystemLegacyWindows::MythSystemLegacyWindows
MythSystemLegacyWindows(MythSystemLegacy *parent)
Definition: mythsystemwindows.cpp:517
MythSystemLegacyWindows
Definition: mythsystemwindows.h:87
MythSystemLegacyIOHandler::wake
void wake()
Definition: mythsystemunix.cpp:251
MythSystemLegacyIOHandler::m_readbuf
std::array< char, 65536 > m_readbuf
Definition: mythsystemunix.h:59
MythSystemLegacyManager::m_jumpAbort
bool m_jumpAbort
Definition: mythsystemunix.h:76
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:48
MythSystemLegacyWindows::m_timeout
SystemTime m_timeout
Definition: mythsystemwindows.h:111
run_system
static bool run_system
Definition: mythsystemwindows.cpp:56
MythSystemLegacyPrivate::error
void error(uint status)
FDType_t::type
int type
Definition: mythsystemwindows.cpp:49
MythSystemLegacyPrivate::GetStatus
uint GetStatus(void)
Definition: mythsystemprivate.h:42
MythSystemLegacyPrivate::GetDirectory
QString & GetDirectory(void)
Definition: mythsystemprivate.h:48
MythSystemLegacyIOHandler::insert
void insert(int fd, QBuffer *buff)
Definition: mythsystemunix.cpp:216
MythSystemLegacyIOHandler::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: mythsystemunix.cpp:88
exitcodes.h
MythSystemLegacyManager::ChildListRebuild
void ChildListRebuild()
Definition: mythsystemwindows.cpp:371
ReferenceCounter::IncrRef
virtual int IncrRef(void)
Increments reference count.
Definition: referencecounter.cpp:101
GENERIC_EXIT_RUNNING
@ GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:26
MythSystemLegacyIOHandler::m_pWaitLock
QMutex m_pWaitLock
Definition: mythsystemunix.h:51
LOC_ERR
#define LOC_ERR
Definition: httplivestream.cpp:49
MythSystemLegacyIOHandler::m_pMap
PMap_t m_pMap
Definition: mythsystemunix.h:54
MythSystemLegacyPrivate::GetCommand
QString & GetCommand(void)
Definition: mythsystemprivate.h:54
MythSystemLegacyPrivate::m_parent
QPointer< MythSystemLegacy > m_parent
Definition: mythsystemprivate.h:40
FDMap_t
QMap< int, FDType_t * > FDMap_t
Definition: mythsystemunix.cpp:48
MythSystemLegacyWindows::Term
void Term(bool force=false) override
Definition: mythsystemwindows.cpp:563
MythSystemLegacyIOHandler::HandleRead
void HandleRead(int fd, QBuffer *buff)
Definition: mythsystemunix.cpp:156