void *client(void *data) { EMsg *msg; EMsgPort *replyport; int i; replyport = e_msgport_new(); msg = g_malloc0(sizeof(*msg)); msg->reply_port = replyport; for (i=0;i<10;i++) { /* synchronous operation */ printf("client: sending\n"); e_msgport_put(server_port, msg); printf("client: waiting for reply\n"); e_msgport_wait(replyport); printf("client: got reply\n"); } printf("client: sleeping ...\n"); g_usleep(2000000); printf("client: sending multiple\n"); for (i=0;i<10;i++) { msg = g_malloc0(sizeof(*msg)); msg->reply_port = replyport; e_msgport_put(server_port, msg); } printf("client: receiving multiple\n"); for (i=0;i<10;i++) { msg = e_msgport_wait(replyport); g_free(msg); } printf("client: done\n"); return NULL; }
int main(int argc, char **argv) { pthread_t serverid, clientid; g_thread_init(NULL); #ifdef G_OS_WIN32 { WSADATA wsadata; if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0) g_error ("Windows Sockets could not be initialized"); } #endif server_port = e_msgport_new(); /*pthread_create(&serverid, NULL, server, (void *)1);*/ pthread_create(&serverid, NULL, fdserver, (void *)1); pthread_create(&clientid, NULL, client, NULL); g_usleep(60000000); return 0; }
/* returns -1 if we didn't wait for reply from thread */ static int cs_waitinfo(void *(worker)(void *), struct _addrinfo_msg *msg, const char *error, CamelException *ex) { EMsgPort *reply_port; pthread_t id; int err, cancel_fd, cancel = 0, fd; cancel_fd = camel_operation_cancel_fd(NULL); if (cancel_fd == -1) { worker(msg); return 0; } reply_port = msg->msg.reply_port = e_msgport_new(); fd = e_msgport_fd(msg->msg.reply_port); if ((err = pthread_create(&id, NULL, worker, msg)) == 0) { int status; #ifndef G_OS_WIN32 struct pollfd polls[2]; polls[0].fd = fd; polls[0].events = POLLIN; polls[1].fd = cancel_fd; polls[1].events = POLLIN; d(printf("waiting for name return/cancellation in main process\n")); do { polls[0].revents = 0; polls[1].revents = 0; status = poll(polls, 2, -1); } while (status == -1 && errno == EINTR); #else fd_set read_set; FD_ZERO(&read_set); FD_SET(fd, &read_set); FD_SET(cancel_fd, &read_set); status = select(MAX(fd, cancel_fd) + 1, &read_set, NULL, NULL, NULL); #endif if (status == -1 || #ifndef G_OS_WIN32 (polls[1].revents & POLLIN) #else FD_ISSET (cancel_fd, &read_set) #endif ) { if (status == -1) camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s", error, #ifndef G_OS_WIN32 g_strerror(errno) #else g_win32_error_message (WSAGetLastError ()) #endif ); else camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Canceled")); /* We cancel so if the thread impl is decent it causes immediate exit. We detach so we dont need to wait for it to exit if it isn't. We check the reply port incase we had a reply in the mean time, which we free later */ d(printf("Canceling lookup thread and leaving it\n")); msg->cancelled = 1; pthread_detach(id); pthread_cancel(id); cancel = 1; } else { struct _addrinfo_msg *reply = (struct _addrinfo_msg *)e_msgport_get(reply_port); g_assert(reply == msg); d(printf("waiting for child to exit\n")); pthread_join(id, NULL); d(printf("child done\n")); } } else { camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s: %s", error, _("cannot create thread"), g_strerror(err)); } e_msgport_destroy(reply_port); return cancel; }