1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/*
* threadtest.c -- test libTw thread-safety
*
*/
#ifndef _REENTRANT
# define _REENTRANT /* for thread-safety */
#endif
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <pthread.h>
#include "Tw/Tw.h"
#include "Tw/Twerrno.h"
tmsgport Thrd_MsgPort;
tmenu Thrd_Menu;
twindow Thrd_Win1, Thrd_Win2;
pthread_t t1, t2;
TW_DECL_MAGIC(threadtest_magic);
byte InitThrd(void) {
if (TwCheckMagic(threadtest_magic) &&
TwOpen(NULL) &&
(Thrd_MsgPort=TwCreateMsgPort
(10, "threadtest", 0, 0, 0)) &&
(Thrd_Menu=TwCreateMenu(
COL(BLACK,WHITE), COL(BLACK,GREEN), COL(HIGH|BLACK,WHITE), COL(HIGH|BLACK,BLACK),
COL(RED,WHITE), COL(RED,GREEN), (byte)0)) &&
TwItem4MenuCommon(Thrd_Menu)) {
TwInfo4Menu(Thrd_Menu, TW_ROW_ACTIVE, 13, " Thread Test ", "ppppppppppppp");
return TRUE;
}
return FALSE;
}
static void Quit(void) {
uldat err, detail;
if ((err = TwErrno)) {
detail = TwErrnoDetail;
fprintf(stderr, "threadtest: libTw error: %s%s\n",
TwStrError(err), TwStrErrorDetail(err, detail));
TwClose();
exit(1);
}
exit(0);
}
long seed;
int fd;
pthread_mutex_t T = PTHREAD_MUTEX_INITIALIZER;
void mainloop(twindow *Win) {
tmsg Msg;
tevent_any Event;
/*struct timeval p = {0, 0};*/
fd_set readfds;
long x, y;
FD_ZERO(&readfds);
srand48(++seed);
if (!(*Win = TwCreateWindow
(11, Win == &Thrd_Win1 ? "threadtest1" : "threadtest2", NULL, Thrd_Menu, COL(HIGH|YELLOW,BLUE),
TW_NOCURSOR, TW_WINDOW_DRAG|TW_WINDOW_CLOSE|TW_WINDOW_RESIZE, TW_WINDOWFL_USECONTENTS,
31 + sizeof(long)/sizeof(hwattr), 16, 0)))
Quit();
TwMapWindow(*Win, TwFirstScreen());
for (;;) {
for (y = 256; y; y--) {
x = lrand48();
TwWriteHWAttrWindow(*Win, lrand48() >> 26, lrand48() >> 27,
sizeof(long)/sizeof(hwattr), (hwattr *)&x);
}
/* bail out if something goes *really* wrong */
if (!TwFlush())
Quit();
/*
* use TwCloneReadMsg() instead of TwReadMsg()
* as the other thread is calling Tw* functions...
* they invalidate the static buffer used by TwReadMsg()
*/
while ((Msg = TwCloneReadMsg(FALSE))) {
Event=&Msg->Event;
if (Msg->Type==TW_MSG_WIDGET_GADGET) {
if (Event->EventGadget.Code == 0)
/* 0 == Close Code */
Quit();
}
TwFreeMem(Msg);
}
/*
FD_SET(fd, &readfds);
p.tv_sec = 0;
p.tv_usec = 10000;
select(fd+1, &readfds, NULL, NULL, &p);
*/
}
}
int main(int argc, char *argv[]) {
if (!InitThrd())
Quit();
fd = TwConnectionFd();
seed = time(NULL);
pthread_create(&t1, NULL, (void *)mainloop, &Thrd_Win2);
usleep(1);
mainloop(&Thrd_Win1);
Quit();
return 0;
}
|