Network package has not been initialized (C API)

I am facing a weird problem when executing Lotus Notes C API’s in multi-threaded environment.

When I execute more than 1 thread, code execution hangs with error description (Network package has not been initialized). When I execute the same piece of code by wrapping Notes API calls in critical section the code works perfectly fine.

I am not very sure whether Lotus Notes C API’s are thread safe or not. Please help me out with this.

Is it so that Notes C API’s are thread safe and I am missing an important compile/link time flag which I should be using to make the code thread safe.

#include <global.h>

#include <dname.h>

#include <ns.h>

#include <osmem.h>

#include <osmisc.h>

#include <stdio.h>

#define MAXUSERNAME 255

#define MAX_NOTES_ERROR 1024

static char* gServerName = NULL;

static int giRef = 0;

/* Uncomment following line to make code thread safe */

/#define WRAP/

#ifdef WRAP

CRITICAL_SECTION gcritAPI;

#endif

void LockCode()

{

#ifdef WRAP

EnterCriticalSection(&gcritAPI);

#endif

}

void UnlockCode()

{

#ifdef WRAP

LeaveCriticalSection(&gcritAPI);

#endif

}

DWORD WINAPI notes_thread(LPVOID data)

{

char *prefix = "notes_thread";

char szCanonServerName[MAXUSERNAME]; /* Canonicalized Name of Server */

STATUS nError;

DWORD dwLoadIndex;

HANDLE hList = NULLHANDLE;



printf("(%s) Inside notes_thread\n",prefix);



LockCode();

if(NotesInitThread() != NOERROR)

{

	printf("(%s) NotesInitThread failed\n",prefix);

	UnlockCode();

	return 0;

}



nError = DNCanonicalize(0L,

	NULL,

	gServerName,

	(char FAR*)szCanonServerName,

	MAXUSERNAME,

	NULL);



UnlockCode();



if (ERR(nError) != NOERROR) {

	printf ("(%s) DNCanonicalize %s failed: %d\n", prefix, gServerName, ERR(nError));

} else {



	printf ("(%s) Calling NSPingServer (%s)\n", prefix, szCanonServerName);



	LockCode();

	/* Call NSPingServer - only interested in result */

	nError = NSPingServer (szCanonServerName, &dwLoadIndex, &hList);

	UnlockCode();



	if(ERR(nError) == NOERROR)

	{

		printf("(%s) NSPingServer call succeeded\n",prefix);

	}

	else

	{

		char szNotesError[MAX_NOTES_ERROR];

		LockCode();

		OSLoadString(NULLHANDLE, ERR(nError), szNotesError,

			MAX_NOTES_ERROR);

		UnlockCode();

		printf("(%s) NSPingServer call failed (%s)\n",prefix,szNotesError);

	}



	if(hList != NULLHANDLE)

	{

		LockCode();

		OSMemFree(hList);

		UnlockCode();

	}

}



LockCode();

NotesTermThread();

giRef--;	

UnlockCode();



printf("(%s) Exiting notes_thread\n",prefix);



return 1;

}

void CreateThreads(int iNum)

{

char *prefix = "CreateThreads";

PROCESS_INFORMATION sProcessInfo;

int i = 0;

	

printf("(%s) Starting %d threads\n", prefix, iNum);



for(i = 0 ; i < iNum ; i++)

{

	int j = i;

	memset(&sProcessInfo,0,sizeof(PROCESS_INFORMATION));



	CreateThread(NULL,

		0,

		notes_thread,

		NULL,

		0,

		NULL);

	giRef++;

}

}

int NotesInitLib()

{

char *prefix = "NotesInitLib";

int iArgc;

char *apchArgv [3];

char zTmp [512];

STATUS nError;



{

	iArgc = 0;



	apchArgv [iArgc++] = strdup ("C:\\Program Files\\IBM\\Lotus\\Notes");



	apchArgv [iArgc] = NULL;



	nError = NotesInitExtended (iArgc, apchArgv);

	if (nError != NOERROR && nError != 421) { /* not ok and not unable to find notes.ini */

		/* try once more  1/2 a second later */

		Sleep (500);

		nError = NotesInitExtended (iArgc, apchArgv);

	}



	for (iArgc = 0; apchArgv [iArgc] != NULL; iArgc++)

		free (apchArgv [iArgc]);



	if (nError != NOERROR) {



		if (nError != 421) {

			printf ("NotesInitExtended error: %d\n", nError);

		}

		printf ("Unable to Initialize Notes!\n");

		return (1);

	}

}

return (0);

}

int main(int argc,char *argv)

{

char *prefix = "main";



if(argc < 2)

{

	printf("Insufficient arguments\n");

	return 0;

}

#ifdef WRAP

InitializeCriticalSection(&gcritAPI);

#endif

gServerName = strdup(argv[1]);



printf("(%s) ServerName: %s\n",prefix,gServerName);



if(NotesInitLib())

{

	printf("Notes initialization failed\n");

}

else

{

	printf("(%s) Calling CreateThreads\n",prefix);

	CreateThreads(10);



	while(giRef != 0)

		Sleep(1000);



	printf("(%s) Calling NotesTerm\n",prefix);

	NotesTerm();

}

#ifdef WRAP

DeleteCriticalSection(&gcritAPI);

#endif

free(gServerName);

}