|
Win32 Thread Primitives & Utils
Submitted by |
Here are some C++ classes the wrap Win32 thread primatives/sync utils and parts of the Winsock API. I hope you can use them.
Any comments on the code, give me a buzz
Have a good one
Dave
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Mutex.cpp] - (383 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#include "Mutex.h"
Mutex::Mutex()
{
m_mutex = ::CreateMutex((SECURITY_ATTRIBUTES*) 0, // use default security attributes
false, // no initial owner
static_cast<char*>(0)); // anonymous mutex
}
Mutex::~Mutex()
{
if (m_mutex != NULL)
{
::CloseHandle(m_mutex);
}
}
|
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Mutex.h] - (425 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#ifndef MUTEX_H
#define MUTEX_H
#include <windows.h>
class Mutex
{
public:
Mutex();
virtual ~Mutex();
public:
inline void get() { if (m_mutex != NULL) ::WaitForSingleObject(m_mutex, INFINITE); }
inline void release() { if (m_mutex != NULL) ::ReleaseMutex(m_mutex); }
private:
HANDLE m_mutex;
};
#endif //MUTEX_H |
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Semaphore.cpp] - (654 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#include "Semaphore.h"
Semaphore::Semaphore()
{
m_handle = ::CreateSemaphore((SECURITY_ATTRIBUTES*)0, 0, 1024, 0);
}
Semaphore::~Semaphore()
{
if (m_handle != NULL)
{
::CloseHandle(m_handle);
}
}
unsigned int Semaphore::wait(unsigned int nSec)
{
DWORD waitRetCode = WAIT_FAILED;
if (m_handle)
{
waitRetCode = ::WaitForSingleObject(m_handle, nSec);
}
return waitRetCode;
}
void Semaphore::signal()
{
if (m_handle)
{
::ReleaseSemaphore(m_handle, 1, NULL);
}
}
unsigned int Semaphore::wait()
{
return wait(INFINITE);
}
|
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Semaphore.h] - (378 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include <windows.h>
class Semaphore
{
public:
Semaphore();
virtual ~Semaphore();
public:
unsigned int wait();
unsigned int wait(unsigned int nSec);
void signal();
private:
HANDLE m_handle;
};
#endif //SEMAPHORE_H |
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Socket.cpp] - (6,291 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#include "Socket.h"
bool Socket::m_init = false;
unsigned int Socket::m_instance = 0;
Socket::Socket() :
m_socket(INVALID_SOCKET),
m_state(Closed)
{
if (m_init == false)
{
WSADATA socketData;
int retCode = ::WSAStartup(0x0101, &socketData);
if (retCode == 0)
{
m_init = true;
}
}
m_instance++;
}
Socket::~Socket()
{
close();
if (m_init == true)
{
m_instance--;
if (m_instance == 0)
{
::WSACleanup();
}
}
}
int Socket::initSocket()
{
if (m_socket == INVALID_SOCKET)
{
m_socket = ::socket(AF_INET, SOCK_STREAM, 0);
if (m_socket != INVALID_SOCKET)
{
m_state = Init;
// Add debug info
#ifdef _DEBUG
int opt = SO_DEBUG;
::setsockopt(m_socket, SOL_SOCKET, 0, (char *)opt, sizeof(opt));
#endif
}
}
return m_socket;
}
void Socket::close()
{
if (m_socket != INVALID_SOCKET)
{
if (::closesocket(m_socket) != SOCKET_ERROR)
{
m_state = Closed;
m_socket = INVALID_SOCKET;
}
}
}
int Socket::connect(const char* hostname, unsigned short port)
{
int retCode = SOCKET_ERROR;
if (m_socket != INVALID_SOCKET && m_state == Init)
{
// Arrives in network host order
struct hostent* host = ::gethostbyname(hostname);
if (host != NULL)
{
unsigned long ipAddress = 0;
::memcpy( (char*) &(ipAddress), host->h_addr, host->h_length );
m_inetAddr.m_address.sin_family = AF_INET; // Socket Type
m_inetAddr.m_address.sin_addr.S_un.S_addr = ipAddress; // IP Address
m_inetAddr.m_address.sin_port = ::htons(port); // Port
retCode = ::connect(m_socket, (struct sockaddr*)&m_inetAddr.m_address, sizeof(struct sockaddr));
if (retCode == 0)
{
m_state = Connected;
}
}
}
return retCode;
}
int Socket::listen(unsigned short port, int backlog)
{
int retCode = SOCKET_ERROR;
if (m_socket != INVALID_SOCKET && m_state == Init)
{
m_inetAddr.m_address.sin_family = AF_INET;
m_inetAddr.m_address.sin_addr.S_un.S_addr = ::htonl(INADDR_ANY); // Listen on Any Address
m_inetAddr.m_address.sin_port = ::htons(port);
retCode = ::bind(m_socket, (struct sockaddr*)&m_inetAddr.m_address, sizeof(m_inetAddr.m_address));
if (retCode == 0)
{
retCode = ::listen(m_socket, backlog);
if (retCode == 0)
{
m_state = Listening;
}
}
}
return retCode;
}
int Socket::accept(Socket& socket)
{
// Close accepting socket
socket.close();
// We must be listening before we can accept
if (m_state == Listening)
{
int length = sizeof(struct sockaddr);
socket.m_socket = ::accept(m_socket, (struct sockaddr*)&socket.m_inetAddr.m_address, &length);
if (socket.m_socket != INVALID_SOCKET)
{
socket.m_state = Connected;
}
else
{
// Didn't accept client so close it down
socket.close();
}
}
return socket.m_socket;
}
unsigned int Socket::sendBuffer(const char* buffer, unsigned int size)
{
int bytesSent = 0;
if (m_state == Connected)
{
bytesSent = ::send(m_socket, buffer, size, 0);
if (bytesSent == 0 || bytesSent == SOCKET_ERROR)
{
close();
}
}
return bytesSent;
}
unsigned int Socket::readBuffer(char* buffer, unsigned int size)
{
int bytesReadTotal = 0;
char* ptr = buffer;
if (m_state == Connected)
{
int bytesRead = 0;
// Always good to make sure we have the whole packet
while (size > 0)
{
bytesRead = ::recv(m_socket, ptr, size, 0);
if (bytesRead == 0 || bytesRead == SOCKET_ERROR)
{
close();
break;
}
size -= bytesRead;
ptr += bytesRead;
bytesReadTotal += bytesRead;
}
}
return bytesReadTotal;
}
Socket& Socket::operator >> (bool& data)
{
if (m_state == Connected)
{
int read = ::recv(m_socket, (char*)&data, sizeof(bool), 0);
if (read == 0 || read == SOCKET_ERROR)
{
close();
}
}
return *this;
}
Socket& Socket::operator >> (char& data)
{
if (m_state == Connected)
{
int read = ::recv(m_socket, &data, sizeof(char), 0);
if (read == 0 || read == SOCKET_ERROR)
{
close();
}
}
return *this;
}
Socket& Socket::operator >> (int& data)
{
if (m_state == Connected)
{
int size = sizeof(int);
int value = 0;
int bytesRead = 0;
while (size > 0)
{
bytesRead = ::recv(m_socket, (char*)&(value)+bytesRead, size, 0);
if (bytesRead == 0 || bytesRead == SOCKET_ERROR)
{
close();
break;
}
size -= bytesRead;
}
if (bytesRead > 0)
{
data = ::ntohl(value);
}
}
return *this;
}
Socket& Socket::operator >> (unsigned int& data)
{
if (m_state == Connected)
{
int size = sizeof(unsigned int);
unsigned int value = 0;
int bytesRead = 0;
while (size > 0)
{
bytesRead = ::recv(m_socket, (char*)&(value)+bytesRead, size, 0);
if (bytesRead == 0 || bytesRead == SOCKET_ERROR)
{
close();
break;
}
size -= bytesRead;
}
if (bytesRead > 0)
{
data = ::ntohl(value);
}
}
return *this;
}
Socket& Socket::operator << (bool data)
{
if (m_state == Connected)
{
int sent = ::send(m_socket, (char*)&data, sizeof(bool), 0);
if (sent == 0 || sent == SOCKET_ERROR)
{
close();
}
}
return *this;
}
Socket& Socket::operator << (char data)
{
if (m_state == Connected)
{
int sent = ::send(m_socket, (char*)&data, sizeof(char), 0);
if (sent == 0 || sent == SOCKET_ERROR)
{
close();
}
}
return *this;
}
Socket& Socket::operator << (int data)
{
if (m_state == Connected)
{
int tmpData = ::htonl(data);
int sent = ::send(m_socket, (char*)&tmpData, sizeof(int), 0);
if (sent == 0 || sent == SOCKET_ERROR)
{
close();
}
}
return *this;
}
Socket& Socket::operator << (unsigned int data)
{
if (m_state == Connected)
{
int tmpData = ::htonl(data);
int sent = ::send(m_socket, (char*)&tmpData, sizeof(unsigned int), 0);
if (sent == 0 || sent == SOCKET_ERROR)
{
close();
}
}
return *this;
}
|
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Socket.h] - (1,634 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#ifndef SOCKET_H
#define SOCKET_H
#include <windows.h>
#include <winsock.h>
#include "InetAddress.h"
class Socket
{
public:
enum SocketState
{
Init,
Closed,
Connected,
Listening
};
public:
Socket();
virtual ~Socket();
public:
int initSocket();
void close();
int connect(const char* hostname, unsigned short port);
int listen(unsigned short port, int backlog = SOMAXCONN);
int accept(Socket& socket);
unsigned int sendBuffer(const char* buffer, unsigned int size);
unsigned int readBuffer(char* buffer, unsigned int size);
Socket& operator >> (bool& data);
Socket& operator >> (char& data);
Socket& operator >> (int& data);
Socket& operator >> (unsigned int& data);
Socket& operator << (bool data);
Socket& operator << (char data);
Socket& operator << (int data);
Socket& operator << (unsigned int data);
static bool m_init;
static unsigned int m_instance;
public:
SocketState getSocketState() { return m_state; }
const InetAddress* getInetAddr() const { return &m_inetAddr; }
public:
inline void clearSet(fd_set& set)
{
FD_ZERO(&set);
}
inline void addSet(fd_set& set)
{
FD_SET(m_socket, &set);
}
inline int isSet(fd_set& set)
{
return FD_ISSET(m_socket, &set);
}
inline void removeSet(fd_set& set)
{
FD_CLR(m_socket, &set);
}
inline int readSelect(fd_set& set)
{
return ::select(0, &set, 0, 0, 0);
}
private:
SocketState m_state;
SOCKET m_socket;
InetAddress m_inetAddr;
};
#endif //SOCKET_H |
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Thread.cpp] - (1,400 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#include "Thread.h"
Thread::Thread(Runnable* runnable) :
m_running(false),
m_run(runnable),
m_threadHandle(0),
m_waiting(false)
{
}
Thread::~Thread()
{
stop();
}
bool Thread::start()
{
if (m_threadHandle == 0)
{
unsigned long threadId = 0;
m_threadHandle = ::CreateThread( (SECURITY_ATTRIBUTES*) 0, // use default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)ThreadProc, // thread start routine
(void*) m_run, // parameter to start routine
0, // creation flags - run immediately
&threadId); // returned thread identifier
if (m_threadHandle != 0)
{
m_running = true;
}
}
return m_running;
}
void Thread::stop()
{
if (m_threadHandle != 0)
{
if (::CloseHandle(m_threadHandle) == TRUE)
{
m_running = false;
m_threadHandle = 0;
if (m_waiting == true)
{
m_semaphore.signal();
m_waiting = false;
}
}
}
}
void Thread::join()
{
if (m_running == true)
{
m_waiting = true;
m_semaphore.wait();
}
}
DWORD WINAPI ThreadProc(LPVOID param)
{
Runnable* runnable = reinterpret_cast<Runnable*>(param);
runnable->runThis();
runnable->stop();
return 0;
}
|
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [Thread.h] - (761 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#ifndef THREAD_H
#define THREAD_H
#pragma warning(disable : 4355)
#include <windows.h>
#include "Semaphore.h"
class Runnable;
class Thread
{
public:
Thread(Runnable* runnable);
virtual ~Thread();
public:
bool start();
void join();
inline bool isRunning() { return m_running; }
private:
void stop();
private:
HANDLE m_threadHandle;
bool m_running;
bool m_waiting;
Runnable* m_run;
Semaphore m_semaphore;
friend DWORD WINAPI ThreadProc(LPVOID param);
};
class Runnable : public Thread
{
protected:
Runnable() : Thread(this)
{}
virtual ~Runnable() {}
public:
virtual void runThis() = 0;
};
#endif //THREAD_H |
|
Currently browsing [threadsyncsockets.zip] (7,491 bytes) - [InetAddress.h] - (697 bytes)
/* Dave Pallot */
/* pallot@iinet.net.au */
/* Copyright 2000 */
#ifndef INETADDRESS_H
#define INETADDRESS_H
#include <string>
#include <winsock.h>
class InetAddress
{
public:
InetAddress() {}
virtual ~InetAddress() {}
public:
/* Returns in Host Byte Order */
unsigned long getULongIP() const
{
return ::ntohl(m_address.sin_addr.S_un.S_addr);
}
/* Returns in Host Byte Order */
unsigned short getPort() const
{
return ::ntohs(m_address.sin_port);
}
std::string getStrIP() const
{
return std::string(::inet_ntoa(m_address.sin_addr));
}
private:
struct sockaddr_in m_address;
friend class Socket;
};
#endif //INETADDRESS_H |
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|