This is the mail archive of the
pthreads-win32@sources.redhat.com
mailing list for the pthreas-win32 project.
Cancelling threads
- To: <pthreads-win32 at sources dot redhat dot com>
- Subject: Cancelling threads
- From: "Ollie Leahy" <ollie at mpt dot ie>
- Date: Mon, 9 Apr 2001 14:37:54 +0100
Reading the FAQ I'm unsure about whether snapshots after
snapshot-1999-11-02 implement asynchronous thread cancelling.
The FAQ makes the following statement:
Snapshot 99-11-02 or earlier only partially supports asynchronous
cancellation.
If the thread you're trying to cancel is blocked (for instance, it could be
waiting for data from the network), it will only get cancelled when it
unblocks
(when the data arrives). Unfortunately, there is no way to do so from
outside the thread.
Does this mean that snapshots after 99-11-02 do completely support
asynchronous cancel? I'm using pthreads-2000-12-29.exe and
the test program below blocks in the accept call and is not cancelled.
The FAQ seems to imply that the thread will be terminated in libraries
built after 1999-11-02, either:
a) This interpretation of the FAQ is not correct and there is
no way to terminate a thread that is blocked in a system call.
or
b) There something else I need to do in order to terminate
the thread blocking in accept()
Can you tell me which is the case?
For what it's worth, the thread is terminated when the same program
is run under Linux.
Thanks,
Ollie Leahy
#include <stdio.h>
#ifndef _WIN32
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#else
#include <windows.h>
#include <winsock.h>
#define sleep(n) Sleep(n * 1000)
#define close(n) closesocket(n)
#endif
#include <pthread.h>
pthread_t t1;
pthread_t t2;
void *
thread1(void *dummy)
{
int oldtype;
int ns, s;
struct sockaddr_in sin;
int len;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket error");
return NULL;
}
memset((char *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(7777);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
printf("bind failed.\n");
return NULL;
}
if (listen(s,8)) {
printf("listen error");
return NULL;
}
printf("Ready to accept a connection\n");
len = sizeof(struct sockaddr_in);
if ((ns = accept(s, (struct sockaddr *)&sin, &len)) < 1) {
printf("accept error");
return NULL;
}
printf("Thread finishing normally.\n");
close(s);
close(ns);
return NULL;
}
int
main(int ac, char ** av)
{
#if defined (_WIN32)
WSADATA junk;
#endif
void * rValue = NULL;
#if defined (_WIN32)
if (WSAStartup(MAKEWORD(2, 0), &junk) != 0) {
return -1;
}
#endif
if (pthread_create(&t1, 0, thread1, 0)) {
printf("pthread_create() thread1 failed\n");
return -1;
}
/*
* Give the thread time to block in accept()
*/
sleep(10);
printf("Canceling thread.\n");
pthread_cancel(t1);
pthread_join(t1, &rValue);
#if defined (_WIN32)
WSACleanup();
#endif
return 0;
}