summaryrefslogtreecommitdiffstats
path: root/examples/thread/semaphores/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/thread/semaphores/main.cpp')
-rw-r--r--examples/thread/semaphores/main.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/examples/thread/semaphores/main.cpp b/examples/thread/semaphores/main.cpp
new file mode 100644
index 0000000..d583c57
--- /dev/null
+++ b/examples/thread/semaphores/main.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. 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 <qapplication.h>
+#include <qwidget.h>
+#include <qpushbutton.h>
+#include <qmultilineedit.h>
+#include <qthread.h>
+#include <qsemaphore.h>
+#include <qmutex.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qlabel.h>
+
+#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"