Sign in to follow this  

_beginthreadex() failure errno 2?

This topic is 3745 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I'm using HawkNL and hawkthreads for a TCP/IP connection. I have a second thread created with the htThreadCreate function. The second thread constantly reads for any received messages.. However, for some reason htThreadCreate fails with a 1 minute period that is, I can only create one again if I have waited for 1 minute after closing my program. When I looked up the htThreadCreate function's contents, I found that _beginthreadex() function fails. Ok, I then googled for its return values and found out that it sets an errno. Then I printed out the errno and to my surprise, it was 2, which is ENOENT, "No such file or directory". How is it possible that a _beginthreadex() can't access a file or directory, it doesn't even have, or does it? I'm confused.. Thank You, Indrek Sünter

Share this post


Link to post
Share on other sites
If it's _beginthreadex() that fails, I don't know what to tell you.

Other than that, a one-minute timeout sounds a lot as if you're not setting SO_REUSEADDR on the socket, so you can't re-bind to the same port within a timeout.

Share this post


Link to post
Share on other sites
I think I'm experiencing a heap or memory corruption and that the errno 2 probably isn't related to the _beginthreadex()..

I don't use the ANDownload function currently, so this function shouldn't be responsible for the thread creating error and a crash that occurs randomly..

Here is the code,
anet.h:

#ifndef ANET_H
#define ANET_H

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <nl.h>
#include <hawkthreads.h>

#if defined WIN32 || defined WIN64
#define WIN32_LEAN_AND_MEAN
#include <allegro.h>
#define AN_MICROSEC 1
#define usleep rest
#else
#include <unistd.h>
#define AN_MICROSEC 1000
#endif

#define AN_BUFFER_SIZE 128

#define ANERR_NONE 0
#define ANERR_INV_PORT 1
#define ANERR_NET_SEL 2
#define ANERR_NL_INIT 3
#define ANERR_NL_OPEN 4
#define ANERR_NL_CONN 5
#define ANERR_COND 6
#define ANERR_THREAD 7
#define ANERR_WRITE 8
#define ANERR_FILE 9
#define ANERR_INV_ADDR 10

typedef unsigned int uint;
typedef bool (* ANReaderCallback) (char *);

// Private variables
extern NLsocket ANSocket;
extern NLaddress ANServerAddress;
extern int ANServerPort;
extern HThreadID ANReaderThread;
extern bool ANShuttingDown;
extern bool ANPauseThread;
extern HTmutex ANMutex;
extern char * ANClientVersion;
extern int ANError;

extern ANReaderCallback ANReader;

// Private function
void *ANThreadReadFunc (void *data);

// Connects if successful
bool ANInit (char *ServerAddr, uint Port, char *ClientName, ANReaderCallback ReaderCallback);
// Disconnects and terminates the thread
void ANDeInit ();
// Sends data to the server
int ANSend (char *Data, uint Size);
// Gets server IP address connected to
char *ANGetServerAddr ();
// Downloads a file from Source to Destination
bool ANDownload (char *Source, char *Destination);
// points to an error or NULL if none
const char *ANGetError ();

#endif


anet.cpp:

#include "anet.h"

NLsocket ANSocket;
NLaddress ANServerAddress;
int ANServerPort = 1;
HThreadID ANReaderThread;
HTcond ANCondition;
bool ANShuttingDown = false;
bool ANPauseThread = false;
HTmutex ANMutex;
char * ANClientVersion = NULL;
int ANError = 0;

ANReaderCallback ANReader = NULL;

void *ANThreadReadFunc (void *data) {
// Nothing we can do here? Quit
if (ANReader == NULL)
return NULL;

// The read buffer
NLbyte Tbuffer [AN_BUFFER_SIZE];
memset (Tbuffer, 0, AN_BUFFER_SIZE);
// Give other threads some time
htThreadYield ();
// Loop forever
while (true) {
// Are we shutting down?
if (ANShuttingDown)
break;
// So, we aren't needed?
if (ANPauseThread) {
htThreadYield ();
continue;
}
// There's a signal? Attempt to fill the buffer then
if (nlRead (ANSocket, Tbuffer, AN_BUFFER_SIZE - 1) > 0) {
// Call the reading callback
if (ANReader (Tbuffer) == true) {
// If done, clear the buffer
memset (Tbuffer, 0, AN_BUFFER_SIZE);
}
}
htThreadYield ();
}
return NULL;
}

bool ANInit (char *ServerAddr, uint Port, char *ClientName, ANReaderCallback ReaderCallback) {
if (ServerAddr == NULL || ReaderCallback == NULL) {
ANError = ANERR_INV_ADDR;
return false;
}

// Copy the callback function pointer
ANReader = ReaderCallback;

if (Port < 0 || Port > 65535) {
ANError = ANERR_INV_PORT;
return false;
}

if (ClientName == NULL) {
ANClientVersion = strdup ("MUDClient v1.0");
} else {
ANClientVersion = strdup (ClientName);
}

// Init the HawkNL
if (!nlInit ()) {
ANError = ANERR_NL_INIT;
return false;
}
if (!nlSelectNetwork (NL_IP)) {
ANError = ANERR_NET_SEL;
return false;
}

// create the NLaddress from ServerAddr
nlGetAddrFromName (ServerAddr, &ANServerAddress);
nlSetAddrPort (&ANServerAddress, Port);
// Try to open a TCP/IP connection and to store the socket in ANet
if ((ANSocket = nlOpen (0, NL_TCP)) == NL_INVALID) {
ANError = ANERR_NL_OPEN;
return false;
}

// Connect if possible
if (!nlConnect (ANSocket, &ANServerAddress)) {
nlClose (ANSocket);
ANError = ANERR_NL_CONN;
return false;
}
// Create a mutex for disabling second thread's access to shared variables
(void) htMutexInit (&ANMutex);
// Disable access
(void) htMutexLock (&ANMutex);
// Create the second thread (no user data, no thread joining)
ANReaderThread = htThreadCreate (ANThreadReadFunc, NULL, true);//false);
// Enable access again
(void) htMutexUnlock (&ANMutex);

// This indicates that htThreadCreate fails sometimes:
if (ANReaderThread == NULL) {
ANError = ANERR_THREAD;
return false;
}

return true;
}

void ANDeInit () {
(void) htMutexLock (&ANMutex);
// We are shutting down..
ANShuttingDown = true;
// Close the socket
nlClose (ANSocket);
(void) htMutexUnlock (&ANMutex);
// Send the thread a signal (to wake it, just in case)
htThreadJoin (ANReaderThread, NULL);
usleep (AN_MICROSEC * 100);
// Shut down HawkNL
nlShutdown ();
// Destroy the mutex and the condition
(void) htMutexDestroy (&ANMutex);
}

int ANSend (char *Data, uint Size) {
int count = 0;
if (Data == NULL || Size < 1 || ANSocket == NL_INVALID)
return false;

// Copy the data to buffer
char *buffer = (char *) malloc (sizeof (char) * (Size + 3));
memset (buffer, 0, sizeof (char) * (Size + 3));
memcpy (buffer, Data, sizeof (char) * Size);
// And add an additional new line ( without this servers can't understand us )
sprintf (buffer, "%s\r\n", buffer);

// Lock the ANSocket
(void) htMutexLock (&ANMutex);
// Send the buffer
if ((count = nlWrite (ANSocket, buffer, strlen (buffer) + 1)) == NL_INVALID) {
(void) htMutexUnlock (&ANMutex);
ANError = ANERR_WRITE;
free (buffer);
return 0;
}
// Unlock it again
(void) htMutexUnlock (&ANMutex);
free (buffer);

return count;
}

char *ANGetServerAddr () {
// Server address string buffer
NLbyte String [128];
memset (String, 0, sizeof (NLbyte) * 128);
// Convert and return the string
return nlAddrToString (&ANServerAddress, String);
}

bool ANDownload (char *Source, char *Destination) {
// Is the given information valid?
if (Source == NULL || Destination == NULL || ANSocket == NL_INVALID) {
return false;
}
// File pointer
FILE *f = NULL;
// File reading buffer
char buffer [1024];
// An empty line for comparison
char emptyline [5];
// A buffer pointer
char *p = NULL;
// Has the information header ended?
bool Started = false;
// How many bytes have we received?
int count = 1;
// How many bytes have we written to file?
int ret = 0;

// Zero allocated memory
memset (buffer, 0, sizeof (buffer));
memset (emptyline, 0, sizeof (emptyline));

// Open the destination file for binary writing
f = fopen (Destination, "wb");
// Is the destination file pointer valid?
if (f) {
// Is the client version string pointer valid?
if (ANClientVersion == NULL) {
// If not, generate one
ANClientVersion = strdup ("MUDClient v1.0");
}
// HTTP1.0 protocol for GETting a file
sprintf (buffer, "GET %s HTTP/1.0\r\nHost:%s\r\nAccept: */*\r\nUser-Agent: %s\r\n\r\n", Source, ANGetServerAddr (), ANClientVersion);

// An empty line for comparison
sprintf (emptyline, "\r\n\r\n");

// Pause the ReaderThread
ANPauseThread = true;
// Lock the ANSocket variable
(void) htMutexLock (&ANMutex);

// Attempt to send the GET message
if (nlWrite (ANSocket, buffer, strlen (buffer) + 1) == NL_INVALID) {
fclose (f);
ANError = ANERR_WRITE;
return false;
}

// A forever-loop for reading the answer
while (true) {
// Reset all counters..
ret = 0;
count = 0;
// Clear the buffer
memset (buffer, 0, sizeof (buffer));
// And read the socket
count = nlRead (ANSocket, buffer, sizeof (buffer));
// An error ocurred?
if (count < 0) {
// Ok, our answer is through
if (nlGetError () == NL_MESSAGE_END) {
break;
} else {
// A more serious "error" has ocurred
fclose (f);
return false;
}
}
// Did we receive something?
if (count > 0) {
// Is the header coming?
if (!Started) {
// Find the empty line
p = strstr (buffer, emptyline);
// We need bytecount without taking the header into account
count -= (p - buffer);
// Ok, we found the empty line..
if (p != NULL) {
// No more headers
Started = true;
// Write down the rest of the buffer (no header)
ret = fwrite (p, 1, sizeof (char) * count, f);
}
} else {
// We have gone past the header and are now just reading and writing everything
ret = fwrite (buffer, 1, sizeof (char) * count, f);
}
}
}
// Unpause the thread
ANPauseThread = false;
// Unlock the ANSocket
(void) htMutexUnlock (&ANMutex);
// Close the file and leave
fclose (f);
return true;
}
// Failed to open the file
ANError = ANERR_FILE;
return false;
}

const char *ANGetError () {
// Get the error ID
NLenum err = nlGetError ();
// A serious system error? Or just a HawkNL error? Get their text equivalents..
if (err != NL_NO_ERROR) {
if (err == NL_SYSTEM_ERROR)
return nlGetSystemErrorStr (nlGetSystemError ());
else
return nlGetErrorStr (err);
}

switch (ANError) {
case ANERR_INV_PORT:
return "Invalid Port";
case ANERR_NET_SEL:
return "Network Selection Failure";
case ANERR_NL_INIT:
return "NLInit Failure";
case ANERR_NL_OPEN:
return "NLOpen Failure";
case ANERR_NL_CONN:
return "NLConnect Failure";
case ANERR_THREAD:
return "Failed to create a thread";
case ANERR_WRITE:
return "Writing failure";
case ANERR_FILE:
return "Invalid File";
case ANERR_INV_ADDR:
return "Invalid Address";
default:
return "No errors";
}
return NULL;
}



The Callback ANReader is here:
a part from main.cpp:

bool get_data(char *data) {
if (data!=NULL) {
int i,j;
bool found=false;
for (i=0,j=0;i<MSL-1;i++) {
if (news[i]!='\0' && found==false) continue;
else found=true;
news[i]=data[j]; j++;
}
news[i]='\0';
}
return TRUE;
}



All suggestions are welcome,
Thank You..

Indrek Sünter

Share this post


Link to post
Share on other sites

This topic is 3745 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this