/**************************************************************************** ** $Id: qt/main.cpp 3.3.6 edited Aug 31 2005 $ ** ** Copyright (C) 1992-2005 Trolltech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #if defined(QT_NO_THREAD) # error Thread support not enabled. #endif // Use pointers to create semaphores after QApplication object! QSemaphore* yellowSem, *greenSem; class YellowThread : public QThread { public: YellowThread(QWidget *o) : receiver(o), stopped(FALSE) { ; } void run(); void stop(); private: QWidget *receiver; QMutex mutex; bool stopped; }; void YellowThread::run() { for (int i = 0; i < 20; i++) { (*yellowSem)++; QCustomEvent *event = new QCustomEvent(12345); event->setData(new QString("Yellow!")); QApplication::postEvent(receiver, event); msleep(200); (*greenSem)--; mutex.lock(); if (stopped) { stopped = FALSE; mutex.unlock(); break; } mutex.unlock(); } (*yellowSem)++; QCustomEvent *event = new QCustomEvent(12346); event->setData(new QString("Yellow!")); QApplication::postEvent(receiver, event); (*greenSem)--; } void YellowThread::stop() { mutex.lock(); stopped = TRUE; mutex.unlock(); } class GreenThread: public QThread { public: GreenThread(QWidget *o) : receiver(o), stopped( FALSE ) { ; } void run(); void stop(); private: QWidget *receiver; QMutex mutex; bool stopped; }; void GreenThread::run() { for (int i = 0; i < 20; i++) { (*greenSem)++; QCustomEvent *event = new QCustomEvent(12345); event->setData(new QString("Green!")); QApplication::postEvent(receiver, event); msleep(200); (*yellowSem)--; mutex.lock(); if (stopped) { stopped = FALSE; mutex.unlock(); break; } mutex.unlock(); } (*greenSem)++; QCustomEvent *event = new QCustomEvent(12346); event->setData(new QString("Green!")); QApplication::postEvent(receiver, event); msleep(10); (*yellowSem)--; } void GreenThread::stop() { mutex.lock(); stopped = TRUE; mutex.unlock(); } class SemaphoreExample : public QWidget { Q_OBJECT public: SemaphoreExample(); ~SemaphoreExample(); void customEvent(QCustomEvent *); public slots: void startExample(); protected: private: QMultiLineEdit *mlineedit; QPushButton *button; QLabel *label; YellowThread yellowThread; GreenThread greenThread; }; SemaphoreExample::SemaphoreExample() : QWidget(), yellowThread(this), greenThread(this) { yellowSem = new QSemaphore(1); greenSem = new QSemaphore(1); button = new QPushButton("&Ignition!", this); connect(button, SIGNAL(clicked()), SLOT(startExample())); mlineedit = new QMultiLineEdit(this); label = new QLabel(this); QVBoxLayout *vbox = new QVBoxLayout(this, 5); vbox->addWidget(button); vbox->addWidget(mlineedit); vbox->addWidget(label); } SemaphoreExample::~SemaphoreExample() { bool stopYellow = yellowThread.running(), stopGreen = greenThread.running(); if (stopYellow) yellowThread.stop(); if (greenThread.running()) greenThread.stop(); if (stopYellow) yellowThread.wait(); if (stopGreen) greenThread.wait(); delete yellowSem; delete greenSem; } void SemaphoreExample::startExample() { if (yellowThread.running() || greenThread.running()) { QMessageBox::information(this, "Sorry", "The threads have not completed yet, and must finish before " "they can be started again."); return; } mlineedit->clear(); while (yellowSem->available() < yellowSem->total()) (*yellowSem)--; (*yellowSem)++; yellowThread.start(); greenThread.start(); } void SemaphoreExample::customEvent(QCustomEvent *event) { switch (event->type()) { case 12345: { QString *s = (QString *) event->data(); mlineedit->append(*s); if (*s == "Green!") label->setBackgroundColor(green); else label->setBackgroundColor(yellow); label->setText(*s); delete s; break; } case 12346: { QString *s = (QString *) event->data(); QMessageBox::information(this, (*s) + " - Finished", "The thread creating the \"" + *s + "\" events has finished."); delete s; break; } default: { qWarning("Unknown custom event type: %d", event->type()); } } } int main(int argc, char **argv) { QApplication app(argc, argv); SemaphoreExample se; app.setMainWidget(&se); se.show(); return app.exec(); } #include "main.moc"