/*************************************************************************** $name: Mutex.c $version: 2.0 $date_modified: 101399 $description: Demonstrates calling mutex functions in not particularly useful ways. $owner: NKS Product Manager Copyright (c) 1999 Novell, Inc. All Rights Reserved. THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE. ****************************************************************************/ #include <nks/synch.h> #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif int GotIt ( NXMutex_t *mutex, int dontBlock, int justFooling ) { int gotit; /* ** This function doesn't really do anything except show the three ways a mutex ** might be manipulated. The code surrounding these calls describes the a bit ** of the semantics of a mutex. Similar extrapolations may be made for the ** reader-writer lock and the semaphore. */ if (dontBlock) { gotit = (NXTryLock(mutex) == TRUE); } else { NXLock(mutex); gotit = TRUE; } if (justFooling && gotit) { NXUnlock(mutex); gotit = FALSE; } return gotit; } void main( void ) { NXMutex_t *mutex; NX_LOCK_INFO_ALLOC(mInfo, "Gotit demonstration mutex", 0); mutex = NXMutexAlloc(0, 0, &mInfo); if (mutex) { // use the mutex here; GotIt demonstrates what can be done with it... } if (mutex) NXMutexFree(mutex); } #if 0 // THIS ILLUSTRATES THE STATIC MUTEX! #include <stdio.h> // (This is only pseudo-code; it doesn't compile.) #include <stdlib.h> #include <string.h> #include <nks/debug.h> #include <nks/synch.h> typedef struct caniche { struct caniche next_poodle; double grooming_expense; int age; NXMutex_t mutex; char name[80]; } poodle_t; NX_LOCK_INFO_ALLOC(mInfo, "A poodle care mutex!", 0); int AddNewPoodle ( poodle_t *kennel ) { poodle_t *new; /*---------------------------------------------------------------------------- ** Here is an alternative sample of a function using a statically allocated ** mutex. This also demonstrates the use of the information structure that can ** be supplied to to the init (or alloc) calls naming the mutex. This feature ** works the same for the reader-writer lock, too. On NetWare, the name shows ** up in the debugger. Here, we also demonstrate the use of the flag to make ** the mutex recursive. **---------------------------------------------------------------------------- */ new = (poodle_t) malloc(sizeof(poodle_t)); if (!new) return -1; err = NXMutexInit(&new->mutex, NX_MUTEX_RECURSIVE, 0, &mInfo); if (err) { free(new); printf("Error initializing mutex:\n%s\n", NXStrError(err)); return (-1); } new->age = ... strcpy(new->name, ... ); // link this dog into the pack... new->next_poodle = kennel; kennel = new; /* ** Do stuff with 'new'--it can be kept safe throughout operations on its data ** by its own mutex. */ new->grooming_expense += 69.95; // (cost of trim) return 0; } void SomeCleanUpFuncToDiscardThePoodle ( poodle_t *poodle ) { /* ** Later, after we've finished using a poodle, uninitialize (including ** discard) the mutex this way. */ NXMutexDeinit(&poodle->mutex); free(poodle); return 0; } #endif