converted to UNIX format.

This commit is contained in:
Gunter Knauf 2004-06-10 21:20:15 +00:00
parent 7b7ac04895
commit ef1aa4e5e9
1 changed files with 300 additions and 300 deletions

View File

@ -1,300 +1,300 @@
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <library.h> #include <library.h>
#include <netware.h> #include <netware.h>
#include <screen.h> #include <screen.h>
#include <nks/thread.h> #include <nks/thread.h>
#include <nks/synch.h> #include <nks/synch.h>
#include "memory.h" #include "memory.h"
#include "memdebug.h" #include "memdebug.h"
typedef struct typedef struct
{ {
int _errno; int _errno;
void *twentybytes; void *twentybytes;
} libthreaddata_t; } libthreaddata_t;
typedef struct typedef struct
{ {
int x; int x;
int y; int y;
int z; int z;
void *tenbytes; void *tenbytes;
NXKey_t perthreadkey; /* if -1, no key obtained... */ NXKey_t perthreadkey; /* if -1, no key obtained... */
NXMutex_t *lock; NXMutex_t *lock;
} libdata_t; } libdata_t;
int gLibId = -1; int gLibId = -1;
void *gLibHandle = (void *) NULL; void *gLibHandle = (void *) NULL;
rtag_t gAllocTag = (rtag_t) NULL; rtag_t gAllocTag = (rtag_t) NULL;
NXMutex_t *gLibLock = (NXMutex_t *) NULL; NXMutex_t *gLibLock = (NXMutex_t *) NULL;
/* internal library function prototypes... */ /* internal library function prototypes... */
int DisposeLibraryData ( void * ); int DisposeLibraryData ( void * );
void DisposeThreadData ( void * ); void DisposeThreadData ( void * );
int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata ); int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
int _NonAppStart( void *NLMHandle, int _NonAppStart( void *NLMHandle,
void *errorScreen, void *errorScreen,
const char *cmdLine, const char *cmdLine,
const char *loadDirPath, const char *loadDirPath,
size_t uninitializedDataLength, size_t uninitializedDataLength,
void *NLMFileHandle, void *NLMFileHandle,
int (*readRoutineP)( int conn, int (*readRoutineP)( int conn,
void *fileHandle, size_t offset, void *fileHandle, size_t offset,
size_t nbytes, size_t nbytes,
size_t *bytesRead, size_t *bytesRead,
void *buffer ), void *buffer ),
size_t customDataOffset, size_t customDataOffset,
size_t customDataSize, size_t customDataSize,
int messageCount, int messageCount,
const char **messages ) const char **messages )
{ {
NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
#ifndef __GNUC__ #ifndef __GNUC__
#pragma unused(cmdLine) #pragma unused(cmdLine)
#pragma unused(loadDirPath) #pragma unused(loadDirPath)
#pragma unused(uninitializedDataLength) #pragma unused(uninitializedDataLength)
#pragma unused(NLMFileHandle) #pragma unused(NLMFileHandle)
#pragma unused(readRoutineP) #pragma unused(readRoutineP)
#pragma unused(customDataOffset) #pragma unused(customDataOffset)
#pragma unused(customDataSize) #pragma unused(customDataSize)
#pragma unused(messageCount) #pragma unused(messageCount)
#pragma unused(messages) #pragma unused(messages)
#endif #endif
/* /*
** Here we process our command line, post errors (to the error screen), ** Here we process our command line, post errors (to the error screen),
** perform initializations and anything else we need to do before being able ** perform initializations and anything else we need to do before being able
** to accept calls into us. If we succeed, we return non-zero and the NetWare ** to accept calls into us. If we succeed, we return non-zero and the NetWare
** Loader will leave us up, otherwise we fail to load and get dumped. ** Loader will leave us up, otherwise we fail to load and get dumped.
*/ */
gAllocTag = AllocateResourceTag(NLMHandle, gAllocTag = AllocateResourceTag(NLMHandle,
"<library-name> memory allocations", "<library-name> memory allocations",
AllocSignature); AllocSignature);
if (!gAllocTag) { if (!gAllocTag) {
OutputToScreen(errorScreen, "Unable to allocate resource tag for " OutputToScreen(errorScreen, "Unable to allocate resource tag for "
"library memory allocations.\n"); "library memory allocations.\n");
return -1; return -1;
} }
gLibId = register_library(DisposeLibraryData); gLibId = register_library(DisposeLibraryData);
if (gLibId < -1) { if (gLibId < -1) {
OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
return -1; return -1;
} }
gLibHandle = NLMHandle; gLibHandle = NLMHandle;
gLibLock = NXMutexAlloc(0, 0, &liblock); gLibLock = NXMutexAlloc(0, 0, &liblock);
if (!gLibLock) { if (!gLibLock) {
OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
return -1; return -1;
} }
return 0; return 0;
} }
/* /*
** Here we clean up any resources we allocated. Resource tags is a big part ** Here we clean up any resources we allocated. Resource tags is a big part
** of what we created, but NetWare doesn't ask us to free those. ** of what we created, but NetWare doesn't ask us to free those.
*/ */
void _NonAppStop( void ) void _NonAppStop( void )
{ {
(void) unregister_library(gLibId); (void) unregister_library(gLibId);
NXMutexFree(gLibLock); NXMutexFree(gLibLock);
} }
/* /*
** This function cannot be the first in the file for if the file is linked ** This function cannot be the first in the file for if the file is linked
** first, then the check-unload function's offset will be nlmname.nlm+0 ** first, then the check-unload function's offset will be nlmname.nlm+0
** which is how to tell that there isn't one. When the check function is ** which is how to tell that there isn't one. When the check function is
** first in the linked objects, it is ambiguous. For this reason, we will ** first in the linked objects, it is ambiguous. For this reason, we will
** put it inside this file after the stop function. ** put it inside this file after the stop function.
** **
** Here we check to see if it's alright to ourselves to be unloaded. If not, ** Here we check to see if it's alright to ourselves to be unloaded. If not,
** we return a non-zero value. Right now, there isn't any reason not to allow ** we return a non-zero value. Right now, there isn't any reason not to allow
** it. ** it.
*/ */
int _NonAppCheckUnload( void ) int _NonAppCheckUnload( void )
{ {
return 0; return 0;
} }
int GetOrSetUpData(int id, libdata_t **appData, int GetOrSetUpData(int id, libdata_t **appData,
libthreaddata_t **threadData ) libthreaddata_t **threadData )
{ {
int err; int err;
libdata_t *app_data; libdata_t *app_data;
libthreaddata_t *thread_data; libthreaddata_t *thread_data;
NXKey_t key; NXKey_t key;
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
err = 0; err = 0;
thread_data = (libthreaddata_t *) NULL; thread_data = (libthreaddata_t *) NULL;
/* /*
** Attempt to get our data for the application calling us. This is where we ** Attempt to get our data for the application calling us. This is where we
** store whatever application-specific information we need to carry in support ** store whatever application-specific information we need to carry in support
** of calling applications. ** of calling applications.
*/ */
app_data = (libdata_t *) get_app_data(id); app_data = (libdata_t *) get_app_data(id);
if (!app_data) { if (!app_data) {
/* /*
** This application hasn't called us before; set up application AND per-thread ** This application hasn't called us before; set up application AND per-thread
** data. Of course, just in case a thread from this same application is calling ** data. Of course, just in case a thread from this same application is calling
** us simultaneously, we better lock our application data-creation mutex. We ** us simultaneously, we better lock our application data-creation mutex. We
** also need to recheck for data after we acquire the lock because WE might be ** also need to recheck for data after we acquire the lock because WE might be
** that other thread that was too late to create the data and the first thread ** that other thread that was too late to create the data and the first thread
** in will have created it. ** in will have created it.
*/ */
NXLock(gLibLock); NXLock(gLibLock);
if (!(app_data = (libdata_t *) get_app_data(id))) { if (!(app_data = (libdata_t *) get_app_data(id))) {
app_data = (libdata_t *) malloc(sizeof(libdata_t)); app_data = (libdata_t *) malloc(sizeof(libdata_t));
if (app_data) { if (app_data) {
memset(app_data, 0, sizeof(libdata_t)); memset(app_data, 0, sizeof(libdata_t));
app_data->tenbytes = malloc(10); app_data->tenbytes = malloc(10);
app_data->lock = NXMutexAlloc(0, 0, &liblock); app_data->lock = NXMutexAlloc(0, 0, &liblock);
if (!app_data->tenbytes || !app_data->lock) { if (!app_data->tenbytes || !app_data->lock) {
if (app_data->lock) if (app_data->lock)
NXMutexFree(app_data->lock); NXMutexFree(app_data->lock);
free(app_data); free(app_data);
app_data = (libdata_t *) NULL; app_data = (libdata_t *) NULL;
err = ENOMEM; err = ENOMEM;
} }
if (app_data) { if (app_data) {
/* /*
** Here we burn in the application data that we were trying to get by calling ** Here we burn in the application data that we were trying to get by calling
** get_app_data(). Next time we call the first function, we'll get this data ** get_app_data(). Next time we call the first function, we'll get this data
** we're just now setting. We also go on here to establish the per-thread data ** we're just now setting. We also go on here to establish the per-thread data
** for the calling thread, something we'll have to do on each application ** for the calling thread, something we'll have to do on each application
** thread the first time it calls us. ** thread the first time it calls us.
*/ */
err = set_app_data(gLibId, app_data); err = set_app_data(gLibId, app_data);
if (err) { if (err) {
free(app_data); free(app_data);
app_data = (libdata_t *) NULL; app_data = (libdata_t *) NULL;
err = ENOMEM; err = ENOMEM;
} }
else { else {
/* create key for thread-specific data... */ /* create key for thread-specific data... */
err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
if (err) /* (no more keys left?) */ if (err) /* (no more keys left?) */
key = -1; key = -1;
app_data->perthreadkey = key; app_data->perthreadkey = key;
} }
} }
} }
} }
NXUnlock(gLibLock); NXUnlock(gLibLock);
} }
if (app_data) { if (app_data) {
key = app_data->perthreadkey; key = app_data->perthreadkey;
if (key != -1 /* couldn't create a key? no thread data */ if (key != -1 /* couldn't create a key? no thread data */
&& !(err = NXKeyGetValue(key, (void **) &thread_data)) && !(err = NXKeyGetValue(key, (void **) &thread_data))
&& !thread_data) { && !thread_data) {
/* /*
** Allocate the per-thread data for the calling thread. Regardless of whether ** Allocate the per-thread data for the calling thread. Regardless of whether
** there was already application data or not, this may be the first call by a ** there was already application data or not, this may be the first call by a
** a new thread. The fact that we allocation 20 bytes on a pointer is not very ** a new thread. The fact that we allocation 20 bytes on a pointer is not very
** important, this just helps to demonstrate that we can have arbitrarily ** important, this just helps to demonstrate that we can have arbitrarily
** complex per-thread data. ** complex per-thread data.
*/ */
thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t)); thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
if (thread_data) { if (thread_data) {
thread_data->_errno = 0; thread_data->_errno = 0;
thread_data->twentybytes = malloc(20); thread_data->twentybytes = malloc(20);
if (!thread_data->twentybytes) { if (!thread_data->twentybytes) {
free(thread_data); free(thread_data);
thread_data = (libthreaddata_t *) NULL; thread_data = (libthreaddata_t *) NULL;
err = ENOMEM; err = ENOMEM;
} }
if ((err = NXKeySetValue(key, thread_data))) { if ((err = NXKeySetValue(key, thread_data))) {
free(thread_data->twentybytes); free(thread_data->twentybytes);
free(thread_data); free(thread_data);
thread_data = (libthreaddata_t *) NULL; thread_data = (libthreaddata_t *) NULL;
} }
} }
} }
} }
if (appData) if (appData)
*appData = app_data; *appData = app_data;
if (threadData) if (threadData)
*threadData = thread_data; *threadData = thread_data;
return err; return err;
} }
int DisposeLibraryData( void *data) int DisposeLibraryData( void *data)
{ {
if (data) { if (data) {
void *tenbytes = ((libdata_t *) data)->tenbytes; void *tenbytes = ((libdata_t *) data)->tenbytes;
if (tenbytes) if (tenbytes)
free(tenbytes); free(tenbytes);
free(data); free(data);
} }
return 0; return 0;
} }
void DisposeThreadData(void *data) void DisposeThreadData(void *data)
{ {
if (data) { if (data) {
void *twentybytes = ((libthreaddata_t *) data)->twentybytes; void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
if (twentybytes) if (twentybytes)
free(twentybytes); free(twentybytes);
free(data); free(data);
} }
} }