#include typedef enum _PROCESSINFOCLASS { ProcessHandleCount = 20, } PROCESSINFOCLASS; typedef LONG NTSTATUS; int GetHandleCount() { static NTSTATUS (*lpNtQueryInformationProcess)( HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ) = NULL; static int bInit = 0; int HandleCount = 0; if (FALSE == bInit) { lpNtQueryInformationProcess = (NTSTATUS ( *)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess"); bInit = 1; } if (NULL != lpNtQueryInformationProcess) { lpNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount, &HandleCount, sizeof(HandleCount), NULL ); } return HandleCount; } #include #include #include #include #include #include #include #include #include pthread_mutex_t mutex; pthread_cond_t cond; pthread_attr_t attr; struct sockaddr_in server; int sockets=2; int threadgroup=5; void *thread_code(void *arg) { int threadnum = (int) arg; int i; int s; char buf[64]; pthread_mutex_lock(&mutex); printf("Thread %d running...\n", threadnum); pthread_mutex_unlock(&mutex); for (i=0; i0) { ++argv; if (!strcmp("-sockets", *argv)) { ++argv; --argc; sockets = atoi(*argv); continue; } if (!strcmp("-threads", *argv)) { ++argv; --argc; threadgroup = atoi(*argv); continue; } printf("Unknown argument: %s\n", *argv);\ printf("Usage: threadtest -s n -t n\n"); printf("where:\n"); printf(" -sockets specifies the number of sockets that each thread should\n"); printf(" use during its life. Interesting values are 0, 1 and\n"); printf(" anything greater than 1. The default value is 2.\n"); printf(" -threads specifies the number of threads to be created simultaneously.\n"); printf(" The default value of 5 is sufficient to demonstrate thread\n"); printf(" and Handle leakage.\n"); exit(1); } printf("Starting... Creating %d threads at a time with each thread using %d sockets\n", threadgroup, sockets); if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "socket() error: %s\n", strerror(errno)); } if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *) &true, sizeof(true)) == -1) { fprintf(stderr, "setsockopt(SO_REUSEADDR) error: %s\n", strerror(errno)); } memset((char *) &server, 0, sizeof(server)); inet_aton("127.0.0.1", &server.sin_addr); server.sin_family = AF_INET; server.sin_port = htons(12345); if(bind(s, (struct sockaddr *) &server, sizeof(server)) == -1) { fprintf(stderr, "bind() error: %s\n", strerror(errno)); } if(listen(s, 2*threadgroup) == -1) { fprintf(stderr, "listen() error: %s\n", strerror(errno)); } sleep(4); if (pthread_mutex_init(&mutex, NULL) != 0) { fprintf(stderr, "Error in pthread_mutex_init\n"); } if (pthread_cond_init(&cond, NULL) != 0) { fprintf(stderr, "Error in pthread_cond_init\n"); } if (pthread_attr_init(&attr) != 0) { fprintf(stderr, "Error in pthread_attr_init\n"); } if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { fprintf(stderr, "Error in pthread_attr_setdetachedstate\n"); } printf("Initial Handle Count: %d\n", GetHandleCount()); for (j=0; j<10; j++) { for (i=0; i