diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-06-26 12:09:00 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-06-26 12:09:00 +0000 |
commit | df90ed95f154046518bf7aae7f88715f25a312db (patch) | |
tree | 104818c62bab65b2988983110fdca9b35927c5e7 /Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c | |
parent | 4e17498848c230539b58d870938a77805039046d (diff) |
libgd 2.1.0
git-svn-id: svn://tug.org/texlive/trunk@30952 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c')
-rw-r--r-- | Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c b/Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c new file mode 100644 index 00000000000..b981a554773 --- /dev/null +++ b/Build/source/libs/gd/libgd-2.1.0/netware/nwlibc.c @@ -0,0 +1,290 @@ +/********************************************************************* + * Universal NetWare library stub. * + * written by Ulrich Neuman and given to OpenSource copyright-free. * + * version: 1.0 * + * $Id$ + *********************************************************************/ + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <library.h> +#include <netware.h> +#include <screen.h> +#include <nks/thread.h> +#include <nks/synch.h> + + +typedef struct { + int _errno; + void *twentybytes; +} libthreaddata_t; + +typedef struct { + int x; + int y; + int z; + void *tenbytes; + NXKey_t perthreadkey; /* if -1, no key obtained... */ + NXMutex_t *lock; +} libdata_t; + +int gLibId = -1; +void *gLibHandle = (void *) NULL; +rtag_t gAllocTag = (rtag_t) NULL; +NXMutex_t *gLibLock = (NXMutex_t *) NULL; + +/* internal library function prototypes... */ +int DisposeLibraryData ( void * ); +void DisposeThreadData ( void * ); +int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata ); + + +int _NonAppStart +( + void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)( int conn, void *fileHandle, size_t offset, + size_t nbytes, size_t *bytesRead, void *buffer ), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages +) +{ + NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); + +#ifndef __GNUC__ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) +#endif + + /* + ** Here we process our command line, post errors (to the error screen), + ** 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 + ** Loader will leave us up, otherwise we fail to load and get dumped. + */ + gAllocTag = AllocateResourceTag(NLMHandle, + "<library-name> memory allocations", AllocSignature); + + if (!gAllocTag) { + OutputToScreen(errorScreen, "Unable to allocate resource tag for " + "library memory allocations.\n"); + return -1; + } + + gLibId = register_library(DisposeLibraryData); + + if (gLibId < -1) { + OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); + return -1; + } + + gLibHandle = NLMHandle; + + gLibLock = NXMutexAlloc(0, 0, &liblock); + + if (!gLibLock) { + OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); + return -1; + } + + return 0; +} + +/* +** 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. +*/ +void _NonAppStop( void ) +{ + (void) unregister_library(gLibId); + NXMutexFree(gLibLock); +} + +/* +** 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 +** 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 +** 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, +** we return a non-zero value. Right now, there isn't any reason not to allow +** it. +*/ +int _NonAppCheckUnload( void ) +{ + return 0; +} + +int GetOrSetUpData +( + int id, + libdata_t **appData, + libthreaddata_t **threadData +) +{ + int err; + libdata_t *app_data; + libthreaddata_t *thread_data; + NXKey_t key; + NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); + + err = 0; + thread_data = (libthreaddata_t *) NULL; + + /* + ** 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 + ** of calling applications. + */ + app_data = (libdata_t *) get_app_data(id); + + if (!app_data) { + /* + ** 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 + ** 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 + ** that other thread that was too late to create the data and the first thread + ** in will have created it. + */ + NXLock(gLibLock); + + if (!(app_data = (libdata_t *) get_app_data(id))) { + app_data = (libdata_t *) malloc(sizeof(libdata_t)); + + if (app_data) { + memset(app_data, 0, sizeof(libdata_t)); + + app_data->tenbytes = malloc(10); + app_data->lock = NXMutexAlloc(0, 0, &liblock); + + if (!app_data->tenbytes || !app_data->lock) { + if (app_data->lock) + NXMutexFree(app_data->lock); + + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } + + if (app_data) { + /* + ** 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 + ** 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 + ** thread the first time it calls us. + */ + err = set_app_data(gLibId, app_data); + + if (err) { + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } else { + /* create key for thread-specific data... */ + err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); + + if (err) /* (no more keys left?) */ + key = -1; + + app_data->perthreadkey = key; + } + } + } + } + + NXUnlock(gLibLock); + } + + if (app_data) { + key = app_data->perthreadkey; + + if ( key != -1 /* couldn't create a key? no thread data */ + && !(err = NXKeyGetValue(key, (void **) &thread_data)) + && !thread_data) { + /* + ** 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 + ** 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 + ** complex per-thread data. + */ + thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t)); + + if (thread_data) { + thread_data->_errno = 0; + thread_data->twentybytes = malloc(20); + + if (!thread_data->twentybytes) { + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + err = ENOMEM; + } + + if ((err = NXKeySetValue(key, thread_data))) { + free(thread_data->twentybytes); + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + } + } + } + } + + if (appData) + *appData = app_data; + + if (threadData) + *threadData = thread_data; + + return err; +} + +int DisposeLibraryData +( + void *data +) +{ + if (data) { + void *tenbytes = ((libdata_t *) data)->tenbytes; + + if (tenbytes) + free(tenbytes); + + free(data); + } + + return 0; +} + +void DisposeThreadData +( + void *data +) +{ + if (data) { + void *twentybytes = ((libthreaddata_t *) data)->twentybytes; + + if (twentybytes) + free(twentybytes); + + free(data); + } +} + + |