00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #define _ENVRNMNT_SOURCE_
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <string.h>
00043
00044 #include "setup.h"
00045
00046 #include "memalloc.h"
00047 #include "prntutil.h"
00048 #include "router.h"
00049 #include "engine.h"
00050 #include "sysdep.h"
00051 #include "utility.h"
00052
00053 #include "envrnmnt.h"
00054
00055 #define SIZE_ENVIRONMENT_HASH 131
00056
00057
00058
00059
00060
00061 #if ALLOW_ENVIRONMENT_GLOBALS
00062 static void AddHashedEnvironment(struct environmentData *);
00063 static struct environmentData *FindEnvironment(unsigned long);
00064 static intBool RemoveHashedEnvironment(struct environmentData *);
00065 static void InitializeEnvironmentHashTable(void);
00066 #endif
00067 static void RemoveEnvironmentCleanupFunctions(struct environmentData *);
00068 static void *CreateEnvironmentDriver(struct symbolHashNode **,struct floatHashNode **,
00069 struct integerHashNode **,struct bitMapHashNode **,
00070 struct externalAddressHashNode **);
00071
00072
00073
00074
00075
00076 #if ALLOW_ENVIRONMENT_GLOBALS
00077 static unsigned long NextEnvironmentIndex = 0;
00078 static struct environmentData **EnvironmentHashTable = NULL;
00079 static struct environmentData *CurrentEnvironment = NULL;
00080 #endif
00081
00082
00083
00084
00085
00086 globle intBool AllocateEnvironmentData(
00087 void *vtheEnvironment,
00088 unsigned int position,
00089 unsigned long size,
00090 void (*cleanupFunction)(void *))
00091 {
00092 struct environmentData *theEnvironment = (struct environmentData *) vtheEnvironment;
00093
00094
00095
00096
00097
00098 if (size <= 0)
00099 {
00100 printf("\n[ENVRNMNT1] Environment data position %d allocated with size of 0 or less.\n",position);
00101 return(FALSE);
00102 }
00103
00104
00105
00106
00107
00108 if (position >= MAXIMUM_ENVIRONMENT_POSITIONS)
00109 {
00110 printf("\n[ENVRNMNT2] Environment data position %d exceeds the maximum allowed.\n",position);
00111 return(FALSE);
00112 }
00113
00114
00115
00116
00117
00118 if (theEnvironment->theData[position] != NULL)
00119 {
00120 printf("\n[ENVRNMNT3] Environment data position %d already allocated.\n",position);
00121 return(FALSE);
00122 }
00123
00124
00125
00126
00127
00128 theEnvironment->theData[position] = malloc(size);
00129 if (theEnvironment->theData[position] == NULL)
00130 {
00131 printf("\n[ENVRNMNT4] Environment data position %d could not be allocated.\n",position);
00132 return(FALSE);
00133 }
00134
00135 memset(theEnvironment->theData[position],0,size);
00136
00137
00138
00139
00140
00141 theEnvironment->cleanupFunctions[position] = cleanupFunction;
00142
00143
00144
00145
00146
00147 return(TRUE);
00148 }
00149
00150
00151
00152
00153
00154
00155 globle intBool DeallocateEnvironmentData()
00156 {
00157 #if ALLOW_ENVIRONMENT_GLOBALS
00158 struct environmentData *theEnvironment, *nextEnvironment;
00159 int i, rv = TRUE;
00160
00161 for (i = 0; i < SIZE_ENVIRONMENT_HASH; i++)
00162 {
00163 for (theEnvironment = EnvironmentHashTable[i];
00164 theEnvironment != NULL;
00165 )
00166 {
00167 nextEnvironment = theEnvironment->next;
00168
00169 if (! DestroyEnvironment(theEnvironment))
00170 { rv = FALSE; }
00171
00172 theEnvironment = nextEnvironment;
00173 }
00174 }
00175
00176 free(EnvironmentHashTable);
00177
00178 return(rv);
00179 #else
00180 return(FALSE);
00181 #endif
00182 }
00183
00184 #if ALLOW_ENVIRONMENT_GLOBALS
00185
00186
00187
00188
00189 static void InitializeEnvironmentHashTable()
00190 {
00191 int i;
00192
00193 if (EnvironmentHashTable != NULL)
00194 { return; }
00195
00196 EnvironmentHashTable = (struct environmentData **)
00197 malloc(sizeof (struct environmentData *) * SIZE_ENVIRONMENT_HASH);
00198
00199 if (EnvironmentHashTable == NULL)
00200 {
00201 printf("\n[ENVRNMNT4] Unable to initialize environment hash table.\n");
00202 return;
00203 }
00204
00205 for (i = 0; i < SIZE_ENVIRONMENT_HASH; i++) EnvironmentHashTable[i] = NULL;
00206 }
00207
00208
00209
00210
00211
00212 static void AddHashedEnvironment(
00213 struct environmentData *theEnvironment)
00214 {
00215 struct environmentData *temp;
00216 unsigned long hashValue;
00217
00218 if (EnvironmentHashTable == NULL)
00219 { InitializeEnvironmentHashTable(); }
00220
00221 hashValue = theEnvironment->environmentIndex % SIZE_ENVIRONMENT_HASH;
00222
00223 temp = EnvironmentHashTable[hashValue];
00224 EnvironmentHashTable[hashValue] = theEnvironment;
00225 theEnvironment->next = temp;
00226 }
00227
00228
00229
00230
00231
00232 static intBool RemoveHashedEnvironment(
00233 struct environmentData *theEnvironment)
00234 {
00235 unsigned long hashValue;
00236 struct environmentData *hptr, *prev;
00237
00238 hashValue = theEnvironment->environmentIndex % SIZE_ENVIRONMENT_HASH;
00239
00240 for (hptr = EnvironmentHashTable[hashValue], prev = NULL;
00241 hptr != NULL;
00242 hptr = hptr->next)
00243 {
00244 if (hptr == theEnvironment)
00245 {
00246 if (prev == NULL)
00247 {
00248 EnvironmentHashTable[hashValue] = hptr->next;
00249 return(TRUE);
00250 }
00251 else
00252 {
00253 prev->next = hptr->next;
00254 return(TRUE);
00255 }
00256 }
00257 prev = hptr;
00258 }
00259
00260 return(FALSE);
00261 }
00262
00263
00264
00265
00266
00267 static struct environmentData *FindEnvironment(
00268 unsigned long environmentIndex)
00269 {
00270 struct environmentData *theEnvironment;
00271 unsigned long hashValue;
00272
00273 hashValue = environmentIndex % SIZE_ENVIRONMENT_HASH;
00274
00275 for (theEnvironment = EnvironmentHashTable[hashValue];
00276 theEnvironment != NULL;
00277 theEnvironment = theEnvironment->next)
00278 {
00279 if (theEnvironment->environmentIndex == environmentIndex)
00280 { return(theEnvironment); }
00281 }
00282
00283 return(NULL);
00284 }
00285 #endif
00286
00287
00288
00289
00290
00291 globle void *CreateEnvironment()
00292 {
00293 return CreateEnvironmentDriver(NULL,NULL,NULL,NULL,NULL);
00294 }
00295
00296
00297
00298
00299
00300 globle void *CreateRuntimeEnvironment(
00301 struct symbolHashNode **symbolTable,
00302 struct floatHashNode **floatTable,
00303 struct integerHashNode **integerTable,
00304 struct bitMapHashNode **bitmapTable)
00305 {
00306 return CreateEnvironmentDriver(symbolTable,floatTable,integerTable,bitmapTable,NULL);
00307 }
00308
00309
00310
00311
00312
00313 globle void *CreateEnvironmentDriver(
00314 struct symbolHashNode **symbolTable,
00315 struct floatHashNode **floatTable,
00316 struct integerHashNode **integerTable,
00317 struct bitMapHashNode **bitmapTable,
00318 struct externalAddressHashNode **externalAddressTable)
00319 {
00320 struct environmentData *theEnvironment;
00321 void *theData;
00322
00323 theEnvironment = (struct environmentData *) malloc(sizeof(struct environmentData));
00324
00325 if (theEnvironment == NULL)
00326 {
00327 printf("\n[ENVRNMNT5] Unable to create new environment.\n");
00328 return(NULL);
00329 }
00330
00331 theData = malloc(sizeof(void *) * MAXIMUM_ENVIRONMENT_POSITIONS);
00332
00333 if (theData == NULL)
00334 {
00335 free(theEnvironment);
00336 printf("\n[ENVRNMNT6] Unable to create environment data.\n");
00337 return(NULL);
00338 }
00339
00340 memset(theData,0,sizeof(void *) * MAXIMUM_ENVIRONMENT_POSITIONS);
00341
00342 theEnvironment->initialized = FALSE;
00343 theEnvironment->theData = (void **) theData;
00344 theEnvironment->next = NULL;
00345 theEnvironment->listOfCleanupEnvironmentFunctions = NULL;
00346 #if ALLOW_ENVIRONMENT_GLOBALS
00347 theEnvironment->environmentIndex = NextEnvironmentIndex++;
00348 #else
00349 theEnvironment->environmentIndex = 0;
00350 #endif
00351 theEnvironment->context = NULL;
00352 theEnvironment->routerContext = NULL;
00353 theEnvironment->functionContext = NULL;
00354 theEnvironment->callbackContext = NULL;
00355
00356
00357
00358
00359
00360 theData = malloc(sizeof(void (*)(struct environmentData *)) * MAXIMUM_ENVIRONMENT_POSITIONS);
00361
00362 if (theData == NULL)
00363 {
00364 free(theEnvironment->theData);
00365 free(theEnvironment);
00366 printf("\n[ENVRNMNT7] Unable to create environment data.\n");
00367 return(NULL);
00368 }
00369
00370 memset(theData,0,sizeof(void (*)(struct environmentData *)) * MAXIMUM_ENVIRONMENT_POSITIONS);
00371 theEnvironment->cleanupFunctions = (void (**)(void *))theData;
00372
00373 #if ALLOW_ENVIRONMENT_GLOBALS
00374 AddHashedEnvironment(theEnvironment);
00375 CurrentEnvironment = theEnvironment;
00376 #endif
00377
00378 EnvInitializeEnvironment(theEnvironment,symbolTable,floatTable,integerTable,bitmapTable,externalAddressTable);
00379
00380 return(theEnvironment);
00381 }
00382
00383 #if ALLOW_ENVIRONMENT_GLOBALS
00384
00385
00386
00387
00388 globle void SetCurrentEnvironment(
00389 void *theEnvironment)
00390 {
00391 CurrentEnvironment = (struct environmentData *) theEnvironment;
00392 }
00393
00394
00395
00396
00397
00398
00399 globle intBool SetCurrentEnvironmentByIndex(
00400 unsigned long environmentIndex)
00401 {
00402 struct environmentData *theEnvironment;
00403
00404 theEnvironment = FindEnvironment(environmentIndex);
00405
00406 if (theEnvironment == NULL)
00407 { return(FALSE); }
00408
00409 SetCurrentEnvironment(theEnvironment);
00410
00411 return(TRUE);
00412 }
00413
00414
00415
00416
00417
00418 globle void *GetEnvironmentByIndex(
00419 unsigned long environmentIndex)
00420 {
00421 struct environmentData *theEnvironment;
00422
00423 theEnvironment = FindEnvironment(environmentIndex);
00424
00425 return(theEnvironment);
00426 }
00427
00428
00429
00430
00431
00432 globle void *GetCurrentEnvironment()
00433 {
00434 return(CurrentEnvironment);
00435 }
00436
00437
00438
00439
00440
00441 globle unsigned long GetEnvironmentIndex(
00442 void *theEnvironment)
00443 {
00444 return(((struct environmentData *) theEnvironment)->environmentIndex);
00445 }
00446
00447 #endif
00448
00449
00450
00451
00452
00453 globle void *GetEnvironmentContext(
00454 void *theEnvironment)
00455 {
00456 return(((struct environmentData *) theEnvironment)->context);
00457 }
00458
00459
00460
00461
00462
00463 globle void *SetEnvironmentContext(
00464 void *theEnvironment,
00465 void *theContext)
00466 {
00467 void *oldContext;
00468
00469 oldContext = ((struct environmentData *) theEnvironment)->context;
00470
00471 ((struct environmentData *) theEnvironment)->context = theContext;
00472
00473 return oldContext;
00474 }
00475
00476
00477
00478
00479
00480 globle void *GetEnvironmentRouterContext(
00481 void *theEnvironment)
00482 {
00483 return(((struct environmentData *) theEnvironment)->routerContext);
00484 }
00485
00486
00487
00488
00489
00490 globle void *SetEnvironmentRouterContext(
00491 void *theEnvironment,
00492 void *theRouterContext)
00493 {
00494 void *oldRouterContext;
00495
00496 oldRouterContext = ((struct environmentData *) theEnvironment)->routerContext;
00497
00498 ((struct environmentData *) theEnvironment)->routerContext = theRouterContext;
00499
00500 return oldRouterContext;
00501 }
00502
00503
00504
00505
00506
00507 globle void *GetEnvironmentFunctionContext(
00508 void *theEnvironment)
00509 {
00510 return(((struct environmentData *) theEnvironment)->functionContext);
00511 }
00512
00513
00514
00515
00516
00517 globle void *SetEnvironmentFunctionContext(
00518 void *theEnvironment,
00519 void *theFunctionContext)
00520 {
00521 void *oldFunctionContext;
00522
00523 oldFunctionContext = ((struct environmentData *) theEnvironment)->functionContext;
00524
00525 ((struct environmentData *) theEnvironment)->functionContext = theFunctionContext;
00526
00527 return oldFunctionContext;
00528 }
00529
00530
00531
00532
00533
00534 globle void *GetEnvironmentCallbackContext(
00535 void *theEnvironment)
00536 {
00537 return(((struct environmentData *) theEnvironment)->callbackContext);
00538 }
00539
00540
00541
00542
00543
00544 globle void *SetEnvironmentCallbackContext(
00545 void *theEnvironment,
00546 void *theCallbackContext)
00547 {
00548 void *oldCallbackContext;
00549
00550 oldCallbackContext = ((struct environmentData *) theEnvironment)->callbackContext;
00551
00552 ((struct environmentData *) theEnvironment)->callbackContext = theCallbackContext;
00553
00554 return oldCallbackContext;
00555 }
00556
00557
00558
00559
00560
00561 globle intBool DestroyEnvironment(
00562 void *vtheEnvironment)
00563 {
00564 struct environmentCleanupFunction *cleanupPtr;
00565 int i;
00566 struct memoryData *theMemData;
00567 intBool rv = TRUE;
00568 struct environmentData *theEnvironment = (struct environmentData *) vtheEnvironment;
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 theMemData = MemoryData(theEnvironment);
00579
00580 EnvReleaseMem(theEnvironment,-1,FALSE);
00581
00582 for (i = 0; i < MAXIMUM_ENVIRONMENT_POSITIONS; i++)
00583 {
00584 if (theEnvironment->cleanupFunctions[i] != NULL)
00585 { (*theEnvironment->cleanupFunctions[i])(theEnvironment); }
00586 }
00587
00588 free(theEnvironment->cleanupFunctions);
00589
00590 for (cleanupPtr = theEnvironment->listOfCleanupEnvironmentFunctions;
00591 cleanupPtr != NULL;
00592 cleanupPtr = cleanupPtr->next)
00593 { (*cleanupPtr->func)(theEnvironment); }
00594
00595 RemoveEnvironmentCleanupFunctions(theEnvironment);
00596
00597 EnvReleaseMem(theEnvironment,-1,FALSE);
00598
00599 #if ALLOW_ENVIRONMENT_GLOBALS
00600 RemoveHashedEnvironment(theEnvironment);
00601 #endif
00602
00603 if ((theMemData->MemoryAmount != 0) || (theMemData->MemoryCalls != 0))
00604 {
00605 printf("\n[ENVRNMNT8] Environment data not fully deallocated.\n");
00606 printf("\n[ENVRNMNT8] MemoryAmount = %ld.\n",(long) theMemData->MemoryAmount);
00607 printf("\n[ENVRNMNT8] MemoryCalls = %ld.\n",(long) theMemData->MemoryCalls);
00608 rv = FALSE;
00609 }
00610
00611 free(theMemData->MemoryTable);
00612
00613 #if BLOCK_MEMORY
00614 ReturnAllBlocks(theEnvironment);
00615 #endif
00616
00617 for (i = 0; i < MAXIMUM_ENVIRONMENT_POSITIONS; i++)
00618 {
00619 if (theEnvironment->theData[i] != NULL)
00620 {
00621 free(theEnvironment->theData[i]);
00622 theEnvironment->theData[i] = NULL;
00623 }
00624 }
00625
00626 free(theEnvironment->theData);
00627
00628 #if ALLOW_ENVIRONMENT_GLOBALS
00629 if (CurrentEnvironment == theEnvironment)
00630 { CurrentEnvironment = NULL; }
00631 #endif
00632
00633 free(theEnvironment);
00634
00635 return(rv);
00636 }
00637
00638
00639
00640
00641
00642 globle intBool AddEnvironmentCleanupFunction(
00643 void *vtheEnv,
00644 char *name,
00645 void (*functionPtr)(void *),
00646 int priority)
00647 {
00648 struct environmentCleanupFunction *newPtr, *currentPtr, *lastPtr = NULL;
00649 struct environmentData *theEnv = (struct environmentData *) vtheEnv;
00650
00651 newPtr = (struct environmentCleanupFunction *) malloc(sizeof(struct environmentCleanupFunction));
00652 if (newPtr == NULL)
00653 { return(FALSE); }
00654
00655 newPtr->name = name;
00656 newPtr->func = functionPtr;
00657 newPtr->priority = priority;
00658
00659 if (theEnv->listOfCleanupEnvironmentFunctions == NULL)
00660 {
00661 newPtr->next = NULL;
00662 theEnv->listOfCleanupEnvironmentFunctions = newPtr;
00663 return(TRUE);
00664 }
00665
00666 currentPtr = theEnv->listOfCleanupEnvironmentFunctions;
00667 while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
00668 {
00669 lastPtr = currentPtr;
00670 currentPtr = currentPtr->next;
00671 }
00672
00673 if (lastPtr == NULL)
00674 {
00675 newPtr->next = theEnv->listOfCleanupEnvironmentFunctions;
00676 theEnv->listOfCleanupEnvironmentFunctions = newPtr;
00677 }
00678 else
00679 {
00680 newPtr->next = currentPtr;
00681 lastPtr->next = newPtr;
00682 }
00683
00684 return(TRUE);
00685 }
00686
00687
00688
00689
00690
00691 static void RemoveEnvironmentCleanupFunctions(
00692 struct environmentData *theEnv)
00693 {
00694 struct environmentCleanupFunction *nextPtr;
00695
00696 while (theEnv->listOfCleanupEnvironmentFunctions != NULL)
00697 {
00698 nextPtr = theEnv->listOfCleanupEnvironmentFunctions->next;
00699 free(theEnv->listOfCleanupEnvironmentFunctions);
00700 theEnv->listOfCleanupEnvironmentFunctions = nextPtr;
00701 }
00702 }