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 #include <stdio.h>
00032 #include <time.h>
00033 #include "../../basext.h"
00034
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 SUPPORT_MULTITHREAD
00066
00067 static SymbolTable MtVariables,SessionTable;
00068 static MUTEX mxMTVariables,mxSessionCounter,mxSessionTable;
00069 static unsigned long lSessionCounter;
00070
00071
00072 typedef struct _SessionInfo {
00073 SHAREDLOCK lckSession;
00074 MUTEX mxSession;
00075 void *pMemSeg;
00076 SymbolTable stSession;
00077 unsigned long lPingTime;
00078 unsigned long lTimeout;
00079 unsigned long lTimeStart;
00080 char *pszId;
00081 struct _SessionInfo *prev,*next;
00082 } SessionInfo, *pSessionInfo;
00083
00084 static pSessionInfo pSessionRoot;
00085
00086 typedef struct _MtClass {
00087 pSessionInfo AssignedSession;
00088 char *pszSessionId;
00089 } MtClass, *pMtClass;
00090
00091 typedef struct _MTVariable{
00092 SHAREDLOCK lckV;
00093 VARIABLE vV;
00094 }MTVariable,*pMTVariable;
00095
00096
00097 #define MT_ERROR_NOSESSION 0x00080001
00098 #define MT_ERROR_BAD_PROG 0x00080002
00099 #define MT_ERROR_BAD_SESS 0x00080003
00100
00101
00102
00103
00104 static pSessionInfo AllocNewSession(pSupportTable pSt,void *p){
00105 pSessionInfo pS;
00106 pS = besPROCALLOC(sizeof(SessionInfo));
00107 if( ! pS )return NULL;
00108 pS->pszId = SymbolName(p);
00109 pS->lTimeStart = time(NULL);
00110
00111 pS->next = pSessionRoot;
00112 pS->prev = NULL;
00113 pSessionRoot = pS;
00114 return pS;
00115 }
00116
00117 static void ReleaseSession(pSupportTable pSt, pSessionInfo pS){
00118
00119 besLockMutex(&mxSessionTable);
00120
00121
00122 if( pS->prev )pS->prev->next = pS->next; else pSessionRoot = pS->next;
00123 if( pS->next )pS->next->prev = pS->prev;
00124
00125 besPROCFREE(pS);
00126
00127 besUnlockMutex(&mxSessionTable);
00128 }
00129
00130
00131
00132
00133
00134 static void time_out_work_thread(void *p){
00135 pSupportTable pSt;
00136 unsigned long lSleepLen;
00137 pSessionInfo pS;
00138 pSt = p;
00139
00140 if( besCONFIGEX(pSt->pEo->pConfig,"httpd.mt.sleep",NULL,NULL,&lSleepLen,NULL,NULL) )
00141 lSleepLen = 60;
00142
00143 while(1){
00144 besSLEEP(lSleepLen);
00145 pS = pSessionRoot;
00146 }
00147
00148
00149 }
00150
00151 #define IsUndef(pVar) ((pVar) == NULL || (pVar)->vType == VTYPE_UNDEF)
00152
00153
00154 besSUB_SHUTDOWN
00155
00156 besEND
00157
00158 besSUB_START
00159 pMtClass pMT;
00160
00161
00162
00163 INC_THREAD_COUNTER
00164
00165
00166
00167
00168 INITLOCK
00169 if( iFirst ){
00170
00171 MtVariables = pSt->NewSymbolTable(pSt->Alloc,besPROCMEMORYSEGMENT);
00172 if( MtVariables == NULL )return COMMAND_ERROR_MEMORY_LOW;
00173
00174 besInitMutex(&mxMTVariables);
00175
00176 SessionTable = pSt->NewSymbolTable(pSt->Alloc,besPROCMEMORYSEGMENT);
00177 if( SessionTable == NULL )return COMMAND_ERROR_MEMORY_LOW;
00178 besInitMutex(&mxSessionCounter);
00179 besInitMutex(&mxSessionTable);
00180
00181 lSessionCounter = (unsigned long)time(NULL);
00182
00183 pSessionRoot = NULL;
00184
00185
00186
00187
00188 iFirst = 0;
00189 }
00190 INITUNLO
00191
00192 besMODULEPOINTER = besALLOC(sizeof(MtClass));
00193 if( besMODULEPOINTER == NULL )return 0;
00194 pMT = (pMtClass)besMODULEPOINTER;
00195 pMT->AssignedSession = NULL;
00196 pMT->pszSessionId = NULL;
00197
00198 return COMMAND_ERROR_SUCCESS;
00199 besEND
00200
00262 besFUNCTION(setsession)
00263 char *pszSession;
00264 pMtClass pMT;
00265 void **p;
00266 VARIABLE Argument;
00267 pSessionInfo pS;
00268 unsigned long i;
00269
00270 pMT = besMODULEPOINTER;
00271 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
00272
00273 Argument = besARGUMENT(1);
00274 besDEREFERENCE(Argument);
00275 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00276 Argument = besCONVERT2STRING(Argument);
00277
00278 for( i = 0 ; i < STRLEN(Argument) ; i++ )
00279 if( ! STRINGVALUE(Argument)[i] )return MT_ERROR_BAD_SESS;
00280
00281 besCONVERT2ZCHAR(Argument,pszSession);
00282
00283 pS = pMT->AssignedSession;
00284 if( pMT->pszSessionId )besFREE(pMT->pszSessionId);
00285 if( pS )besUnlockSharedRead(&(pS->lckSession));
00286 pS = pMT->AssignedSession = NULL;
00287
00288 besLockMutex(&mxSessionTable);
00289 p = pSt->LookupSymbol(pszSession,SessionTable,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00290 if( p == NULL ){
00291 besUnlockMutex(&mxSessionTable);
00292 besFREE(pszSession);
00293 return COMMAND_ERROR_MEMORY_LOW;
00294 }
00295 if( *p == NULL ){
00296
00297 besLockMutex(&mxSessionCounter);
00298 lSessionCounter++;
00299 besUnlockMutex(&mxSessionCounter);
00300
00301 *p = AllocNewSession(pSt,p);
00302 if( *p == NULL ){
00303 besUnlockMutex(&mxSessionTable);
00304 return COMMAND_ERROR_MEMORY_LOW;
00305 }
00306 pS = pMT->AssignedSession = *p;
00307 besInitMutex(&(pS->mxSession));
00308 besInitSharedLock(&(pS->lckSession));
00309 besLockSharedRead(&(pS->lckSession));
00310
00311 pS->pMemSeg = besINIT_SEGMENT(pSt->pEo->pMemorySegment,NULL);
00312 if( pS->pMemSeg == NULL )return COMMAND_ERROR_MEMORY_LOW;
00313 pS->stSession = pSt->NewSymbolTable(pSt->Alloc,pS->pMemSeg);
00314 if( pS->stSession == NULL )return COMMAND_ERROR_MEMORY_LOW;
00315 besUnlockMutex(&mxSessionTable);
00316 }else{
00317 pS = *p;
00318 besLockSharedRead(&(pS->lckSession));
00319 besUnlockMutex(&mxSessionTable);
00320 }
00321
00322
00323
00324
00325 pMT->pszSessionId = besALLOC(strlen(SymbolName(p))+1);
00326 if( pMT->pszSessionId == NULL )return COMMAND_ERROR_MEMORY_LOW;
00327 strcpy(pMT->pszSessionId,SymbolName(p));
00328 pMT->AssignedSession = pS;
00329 pS->lPingTime = time(NULL);
00330 besUnlockSharedRead(&(pS->lckSession));
00331
00332 besEND
00333
00349 besFUNCTION(chksession)
00350 char *pszSession;
00351 pMtClass pMT;
00352 void **p;
00353 VARIABLE Argument;
00354 pSessionInfo pS;
00355 unsigned long i;
00356
00357 besRETURNVALUE = NULL;
00358 pMT = besMODULEPOINTER;
00359 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
00360
00361 Argument = besARGUMENT(1);
00362 besDEREFERENCE(Argument);
00363 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00364 Argument = besCONVERT2STRING(Argument);
00365
00366 for( i = 0 ; i < STRLEN(Argument) ; i++ )
00367 if( ! STRINGVALUE(Argument)[i] )return MT_ERROR_BAD_SESS;
00368
00369 besCONVERT2ZCHAR(Argument,pszSession);
00370
00371 pS = pMT->AssignedSession = NULL;
00372 besLockMutex(&mxSessionTable);
00373 p = pSt->LookupSymbol(pszSession,SessionTable,0,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00374 besUnlockMutex(&mxSessionTable);
00375 besFREE(pszSession);
00376 besALLOC_RETURN_LONG;
00377 LONGVALUE(besRETURNVALUE) = p == NULL ? 0 : -1 ;
00378 return COMMAND_ERROR_SUCCESS;
00379 besEND
00380
00387 besFUNCTION(sessioncount)
00388 besALLOC_RETURN_LONG;
00389
00390 besLockMutex(&mxSessionCounter);
00391 LONGVALUE(besRETURNVALUE) = lSessionCounter;
00392 besUnlockMutex(&mxSessionCounter);
00393 return COMMAND_ERROR_SUCCESS;
00394 besEND
00395
00410 besFUNCTION(newsession)
00411 unsigned long lThisSession;
00412 MD5_CTX Context;
00413 unsigned char digest[16];
00414 int i;
00415 pMtClass pMT;
00416 void **p;
00417 pSessionInfo pS;
00418 VARIABLE Argument;
00419
00420 pMT = besMODULEPOINTER;
00421 Argument = NULL;
00422 if( besARGNR > 0 ){
00423 Argument = besARGUMENT(1);
00424 besDEREFERENCE(Argument);
00425 if( Argument){
00426 Argument = besCONVERT2STRING(Argument);
00427 }
00428 }
00429
00430
00431 besLockMutex(&mxSessionCounter);
00432 lThisSession = lSessionCounter++;
00433 besUnlockMutex(&mxSessionCounter);
00434
00435
00436 besMD5INIT(&Context);
00437 besMD5UPDATE(&Context,(unsigned char *)&lThisSession,sizeof(unsigned long));
00438 if( Argument )besMD5UPDATE(&Context,(unsigned char *)STRINGVALUE(Argument),STRLEN(Argument));
00439 besMD5FINAL(digest,&Context);
00440 besALLOC_RETURN_STRING(33);
00441 STRLEN(besRETURNVALUE) = 32;
00442
00443 for( i = 0 ; i < 16 ; i++ ){
00444 STRINGVALUE(besRETURNVALUE)[2*i] = 'A' + (digest[i]&0x0F);
00445 digest[i] >>= 4;
00446 STRINGVALUE(besRETURNVALUE)[2*i+1] = 'A' + (digest[i]&0x0F);
00447 }
00448 STRINGVALUE(besRETURNVALUE)[32] = (char)0;
00449
00450 pMT->AssignedSession = NULL;
00451 if( pMT->pszSessionId )besFREE(pMT->pszSessionId);
00452 besLockMutex(&mxSessionTable);
00453 p = pSt->LookupSymbol(STRINGVALUE(besRETURNVALUE),SessionTable,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00454 if( p == NULL ){
00455 besUnlockMutex(&mxSessionTable);
00456 return COMMAND_ERROR_MEMORY_LOW;
00457 }
00458 if( *p == NULL ){
00459 *p = AllocNewSession(pSt,p);
00460 if( *p == NULL ){
00461 besUnlockMutex(&mxSessionTable);
00462 return COMMAND_ERROR_MEMORY_LOW;
00463 }
00464 pS = pMT->AssignedSession = *p;
00465 pS-> lPingTime = time(NULL);
00466 besInitMutex(&(pS->mxSession));
00467 besInitSharedLock(&(pS->lckSession));
00468 besLockSharedRead(&(pS->lckSession));
00469
00470 pS->pMemSeg = besINIT_SEGMENT(pSt->pEo->pMemorySegment,NULL);
00471 if( pS->pMemSeg == NULL )return COMMAND_ERROR_MEMORY_LOW;
00472 pS->stSession = pSt->NewSymbolTable(pSt->Alloc,pS->pMemSeg);
00473 if( pS->stSession == NULL )return COMMAND_ERROR_MEMORY_LOW;
00474 besUnlockMutex(&mxSessionTable);
00475 }else{
00476 pS = *p;
00477 besLockSharedRead(&(pS->lckSession));
00478 besUnlockMutex(&mxSessionTable);
00479 }
00480 pMT->pszSessionId = besALLOC(strlen(SymbolName(p))+1);
00481 if( pMT->pszSessionId == NULL )return COMMAND_ERROR_MEMORY_LOW;
00482 strcpy(pMT->pszSessionId,SymbolName(p));
00483 pMT->AssignedSession = pS;
00484 pS->lPingTime = time(NULL);
00485 besUnlockSharedRead(&(pS->lckSession));
00486
00487 besEND
00488
00489 static void FinishSegmentCallBack(char *SymbolName, void *SymbolValue, void *f){
00490 pSupportTable pSt;
00491 pMTVariable p;
00492
00493
00494 pSt = f;
00495 p = SymbolValue;
00496 besFinishSharedLock(&(p->lckV));
00497 }
00498
00508 besFUNCTION(delsession)
00509 char *pszSession;
00510 void **p;
00511 VARIABLE Argument;
00512 pSessionInfo pS;
00513 pMtClass pMT;
00514 int bSessDef;
00515
00516
00517 pMT = besMODULEPOINTER;
00518 pS = pMT->AssignedSession;
00519
00520 besRETURNVALUE = NULL;
00521
00522 Argument = besARGUMENT(1);
00523 besDEREFERENCE(Argument);
00524 bSessDef = 0;
00525 if( Argument == NULL ){
00526
00527 bSessDef = 1;
00528 pszSession = pMT->pszSessionId;
00529 if( pszSession == NULL )return MT_ERROR_NOSESSION;
00530 }else{
00531 Argument = besCONVERT2STRING(Argument);
00532 besCONVERT2ZCHAR(Argument,pszSession);
00533 }
00534
00535
00536
00537
00538 if( bSessDef || (pMT->pszSessionId && !strcmp(pszSession,pMT->pszSessionId)) ){
00539 besUnlockSharedRead(&(pS->lckSession));
00540 pMT->pszSessionId;
00541 pMT->AssignedSession = NULL;
00542 }
00543
00544 besLockMutex(&mxSessionTable);
00545 p = pSt->LookupSymbol(pszSession,SessionTable,0,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00546
00547
00548 if( p == NULL ){
00549 besUnlockMutex(&mxSessionTable);
00550 if( ! bSessDef )besFREE(pszSession);
00551 return COMMAND_ERROR_SUCCESS;
00552 }
00553
00554 pS = *p;
00555
00556
00557 pSt->DeleteSymbol(pszSession,SessionTable,pSt->Free,besPROCMEMORYSEGMENT);
00558 besUnlockMutex(&mxSessionTable);
00559
00560
00561 if( pS == NULL ){
00562
00563 if( ! bSessDef )besFREE(pszSession);
00564 return EXE_ERROR_INTERNAL;
00565 }
00566
00567
00568
00569 besLockSharedWrite(&(pS->lckSession));
00570
00571
00572
00573
00574
00575
00576 besTRAVERSESYMBOLTABLE(pS->stSession,FinishSegmentCallBack,pSt);
00577
00578
00579
00580 besFINISH_SEGMENT(pS->pMemSeg);
00581
00582 besFinishMutex(&(pS->mxSession));
00583
00584
00585 besUnlockSharedWrite(&(pS->lckSession));
00586
00587 besFinishSharedLock(&(pS->lckSession));
00588
00589 ReleaseSession(pSt,pS);
00590
00591
00592
00593
00594 if( ! bSessDef )besFREE(pszSession);
00595 besEND
00596
00606 besFUNCTION(getsession)
00607 pMtClass pMT;
00608 char *s;
00609
00610 pMT = besMODULEPOINTER;
00611 s = pMT->pszSessionId;
00612 besRETURNVALUE = NULL;
00613 if( pMT->AssignedSession == NULL )return COMMAND_ERROR_SUCCESS;
00614 besALLOC_RETURN_STRING(strlen(s));
00615 memcpy(STRINGVALUE(besRETURNVALUE),s,strlen(s));
00616 return COMMAND_ERROR_SUCCESS;
00617 besEND
00618
00627 besFUNCTION(setsvariable)
00628 VARIABLE Argument;
00629 char *pszVariableName;
00630 pMTVariable *p;
00631 pMtClass pMT;
00632 pSessionInfo pS;
00633
00634 besRETURNVALUE = NULL;
00635 pMT = besMODULEPOINTER;
00636 pS = pMT->AssignedSession;
00637
00638 if( besARGNR < 2 )return COMMAND_ERROR_FEW_ARGS;
00639
00640 Argument = besARGUMENT(1);
00641 besDEREFERENCE(Argument);
00642 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00643 Argument = besCONVERT2STRING(Argument);
00644 besCONVERT2ZCHAR(Argument,pszVariableName);
00645
00646 besLockMutex(&(pS->mxSession));
00647 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,pS->stSession,1,pSt->Alloc,pSt->Free,pS->pMemSeg);
00648 besFREE(pszVariableName);
00649 if( p == NULL ){
00650 besUnlockMutex(&(pS->mxSession));
00651 return COMMAND_ERROR_MEMORY_LOW;
00652 }
00653
00654 if( *p == NULL ){
00655 *p = pSt->Alloc(sizeof(MTVariable),pS->pMemSeg);
00656 if( *p == NULL ){
00657 besUnlockMutex(&(pS->mxSession));
00658 return COMMAND_ERROR_MEMORY_LOW;
00659 }
00660 besInitSharedLock(&((*p)->lckV));
00661 (*p)->vV = NULL;
00662 }
00663 besUnlockMutex(&(pS->mxSession));
00664
00665 besLockSharedWrite(&((*p)->lckV));
00666
00667 Argument = besARGUMENT(2);
00668 besDEREFERENCE(Argument);
00669
00670 if( (*p)->vV && TYPE((*p)->vV) == VTYPE_STRING && STRINGVALUE((*p)->vV) ){
00671 pSt->Free(STRINGVALUE((*p)->vV),pS->pMemSeg);
00672 STRINGVALUE((*p)->vV) = NULL;
00673 }
00674
00675
00676 if( IsUndef(Argument) ){
00677 if( (*p)->vV )pSt->Free((*p)->vV,pS->pMemSeg);
00678 (*p)->vV = NULL;
00679 besUnlockSharedWrite(&((*p)->lckV));
00680 return COMMAND_ERROR_SUCCESS;
00681 }
00682
00683 if( (*p)->vV == NULL )(*p)->vV = pSt->Alloc(sizeof(FixSizeMemoryObject),pS->pMemSeg);
00684 if( (*p)->vV == NULL ){
00685 besUnlockSharedWrite(&((*p)->lckV));
00686 return COMMAND_ERROR_MEMORY_LOW;
00687 }
00688
00689 (*p)->vV->sType = 0;
00690 (*p)->vV->State = STATE_UNKNOWN;
00691 (*p)->vV->next = NULL;
00692 (*p)->vV->link.prev = NULL;
00693 (*p)->vV->ArrayHighLimit = 0;
00694 (*p)->vV->ArrayLowLimit = 1;
00695
00696 if( TYPE(Argument) == VTYPE_STRING ){
00697 (*p)->vV->Value.pValue = pSt->Alloc(STRLEN(Argument) ? STRLEN(Argument) : 1 ,pS->pMemSeg);
00698 if( (*p)->vV->Value.pValue == NULL ){
00699 pSt->Free((*p)->vV,pS->pMemSeg);
00700 (*p)->vV = NULL;
00701 besUnlockSharedWrite(&((*p)->lckV));
00702 return COMMAND_ERROR_MEMORY_LOW;
00703 }
00704 memcpy((*p)->vV->Value.pValue,STRINGVALUE(Argument),STRLEN(Argument));
00705 (*p)->vV->Size = STRLEN(Argument);
00706 TYPE((*p)->vV) = VTYPE_STRING;
00707 besUnlockSharedWrite(&((*p)->lckV));
00708 return COMMAND_ERROR_SUCCESS;
00709 }
00710
00711 if( TYPE(Argument) == VTYPE_LONG || TYPE(Argument) == VTYPE_DOUBLE ){
00712 TYPE((*p)->vV) = TYPE(Argument);
00713 (*p)->vV->Size = 0;
00714 (*p)->vV->Value = Argument->Value;
00715 besUnlockSharedWrite(&((*p)->lckV));
00716 return COMMAND_ERROR_SUCCESS;
00717 }
00718
00719 besUnlockSharedWrite(&((*p)->lckV));
00720 return EXE_ERROR_INTERNAL;
00721 besEND
00722
00732 besFUNCTION(getsvariable)
00733 VARIABLE Argument;
00734 char *pszVariableName;
00735 pMTVariable *p;
00736 pMtClass pMT;
00737 pSessionInfo pS;
00738
00739 besRETURNVALUE = NULL;
00740 pMT = besMODULEPOINTER;
00741 pS = pMT->AssignedSession;
00742
00743 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
00744
00745 Argument = besARGUMENT(1);
00746 besDEREFERENCE(Argument);
00747 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00748 Argument = besCONVERT2STRING(Argument);
00749 besCONVERT2ZCHAR(Argument,pszVariableName);
00750
00751 besLockMutex(&(pS->mxSession));
00752 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,pS->stSession,0,pSt->Alloc,pSt->Free,pS->pMemSeg);
00753 besFREE(pszVariableName);
00754 if( p == NULL ){
00755 besUnlockMutex(&(pS->mxSession));
00756 return COMMAND_ERROR_SUCCESS;
00757 }
00758
00759 if( *p == NULL ){
00760 besUnlockMutex(&(pS->mxSession));
00761 return COMMAND_ERROR_SUCCESS;
00762 }
00763 besUnlockMutex(&(pS->mxSession));
00764
00765 if( (*p)->vV == NULL )return COMMAND_ERROR_SUCCESS;
00766
00767 besLockSharedRead(&((*p)->lckV));
00768
00769 if( TYPE((*p)->vV) == VTYPE_STRING ){
00770 besALLOC_RETURN_STRING(STRLEN( (*p)->vV ));
00771 memcpy(STRINGVALUE(besRETURNVALUE),STRINGVALUE( (*p)->vV ),STRLEN( (*p)->vV) );
00772 besUnlockSharedRead(&((*p)->lckV));
00773 return COMMAND_ERROR_SUCCESS;
00774 }
00775
00776 if( TYPE((*p)->vV) == VTYPE_LONG ){
00777 besALLOC_RETURN_LONG;
00778 LONGVALUE(besRETURNVALUE) = LONGVALUE((*p)->vV);
00779 besUnlockSharedRead(&((*p)->lckV));
00780 return COMMAND_ERROR_SUCCESS;
00781 }
00782
00783 if( TYPE((*p)->vV) == VTYPE_DOUBLE ){
00784 besALLOC_RETURN_DOUBLE;
00785 DOUBLEVALUE(besRETURNVALUE) = DOUBLEVALUE((*p)->vV);
00786 besUnlockSharedRead(&((*p)->lckV));
00787 return COMMAND_ERROR_SUCCESS;
00788 }
00789
00790 return EXE_ERROR_INTERNAL;
00791 besEND
00792
00803 besFUNCTION(setmtvariable)
00804 VARIABLE Argument;
00805 char *pszVariableName;
00806 pMTVariable *p;
00807 besRETURNVALUE = NULL;
00808
00809 if( besARGNR < 2 )return COMMAND_ERROR_FEW_ARGS;
00810
00811 Argument = besARGUMENT(1);
00812 besDEREFERENCE(Argument);
00813 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00814 Argument = besCONVERT2STRING(Argument);
00815 besCONVERT2ZCHAR(Argument,pszVariableName);
00816
00817 besLockMutex(&mxMTVariables);
00818 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00819 besFREE(pszVariableName);
00820 if( p == NULL ){
00821 besUnlockMutex(&mxMTVariables);
00822 return COMMAND_ERROR_MEMORY_LOW;
00823 }
00824
00825
00826 if( *p == NULL ){
00827 *p = besPROCALLOC(sizeof(MTVariable));
00828 if( *p == NULL ){
00829 besUnlockMutex(&mxMTVariables);
00830 return COMMAND_ERROR_MEMORY_LOW;
00831 }
00832 besInitSharedLock(&((*p)->lckV));
00833
00834 (*p)->vV = NULL;
00835 }
00836 besUnlockMutex(&mxMTVariables);
00837
00838 besLockSharedWrite(&((*p)->lckV));
00839
00840 Argument = besARGUMENT(2);
00841 besDEREFERENCE(Argument);
00842
00843
00844 if( (*p)->vV && TYPE((*p)->vV) == VTYPE_STRING && STRINGVALUE((*p)->vV) ){
00845 besPROCFREE(STRINGVALUE((*p)->vV));
00846 STRINGVALUE((*p)->vV) = NULL;
00847 }
00848
00849
00850 if( IsUndef(Argument) ){
00851 if( (*p)->vV )besPROCFREE((*p)->vV);
00852 (*p)->vV = NULL;
00853 besUnlockSharedWrite(&((*p)->lckV));
00854 return COMMAND_ERROR_SUCCESS;
00855 }
00856
00857 if( (*p)->vV == NULL )(*p)->vV = besPROCALLOC(sizeof(FixSizeMemoryObject));
00858 if( (*p)->vV == NULL ){
00859 besUnlockSharedWrite(&((*p)->lckV));
00860 return COMMAND_ERROR_MEMORY_LOW;
00861 }
00862
00863 (*p)->vV->sType = 0;
00864 (*p)->vV->State = STATE_UNKNOWN;
00865 (*p)->vV->next = NULL;
00866 (*p)->vV->link.prev = NULL;
00867 (*p)->vV->ArrayHighLimit = 0;
00868 (*p)->vV->ArrayLowLimit = 1;
00869
00870 if( TYPE(Argument) == VTYPE_STRING ){
00871 (*p)->vV->Value.pValue = besPROCALLOC(STRLEN(Argument) ? STRLEN(Argument) : 1 );
00872 if( (*p)->vV->Value.pValue == NULL ){
00873 besUnlockSharedWrite(&((*p)->lckV));
00874 return COMMAND_ERROR_MEMORY_LOW;
00875 }
00876 memcpy((*p)->vV->Value.pValue,STRINGVALUE(Argument),STRLEN(Argument));
00877 (*p)->vV->Size = STRLEN(Argument);
00878 TYPE((*p)->vV) = VTYPE_STRING;
00879 besUnlockSharedWrite(&((*p)->lckV));
00880 return COMMAND_ERROR_SUCCESS;
00881 }
00882
00883 if( TYPE(Argument) == VTYPE_LONG || TYPE(Argument) == VTYPE_DOUBLE ){
00884 TYPE((*p)->vV) = TYPE(Argument);
00885 (*p)->vV->Size = 0;
00886 (*p)->vV->Value = Argument->Value;
00887 besUnlockSharedWrite(&((*p)->lckV));
00888 return COMMAND_ERROR_SUCCESS;
00889 }
00890
00891 besUnlockSharedWrite(&((*p)->lckV));
00892 return EXE_ERROR_INTERNAL;
00893 besEND
00894
00901 besFUNCTION(getmtvariable)
00902 VARIABLE Argument;
00903 char *pszVariableName;
00904 pMTVariable *p;
00905 besRETURNVALUE = NULL;
00906
00907 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
00908
00909 Argument = besARGUMENT(1);
00910 besDEREFERENCE(Argument);
00911 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00912 Argument = besCONVERT2STRING(Argument);
00913 besCONVERT2ZCHAR(Argument,pszVariableName);
00914
00915 besLockMutex(&mxMTVariables);
00916 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,0,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
00917 besFREE(pszVariableName);
00918 if( p == NULL ){
00919 besUnlockMutex(&mxMTVariables);
00920 return COMMAND_ERROR_SUCCESS;
00921 }
00922
00923 if( *p == NULL ){
00924 besUnlockMutex(&mxMTVariables);
00925 return COMMAND_ERROR_SUCCESS;
00926 }
00927 besUnlockMutex(&mxMTVariables);
00928
00929 if( (*p)->vV == NULL )return COMMAND_ERROR_SUCCESS;
00930
00931 besLockSharedRead(&((*p)->lckV));
00932
00933 if( TYPE((*p)->vV) == VTYPE_STRING ){
00934 besALLOC_RETURN_STRING(STRLEN( (*p)->vV ));
00935 memcpy(STRINGVALUE(besRETURNVALUE),STRINGVALUE( (*p)->vV ),STRLEN( (*p)->vV) );
00936 besUnlockSharedRead(&((*p)->lckV));
00937 return COMMAND_ERROR_SUCCESS;
00938 }
00939
00940 if( TYPE((*p)->vV) == VTYPE_LONG ){
00941 besALLOC_RETURN_LONG;
00942 LONGVALUE(besRETURNVALUE) = LONGVALUE((*p)->vV);
00943 besUnlockSharedRead(&((*p)->lckV));
00944 return COMMAND_ERROR_SUCCESS;
00945 }
00946
00947 if( TYPE((*p)->vV) == VTYPE_DOUBLE ){
00948 besALLOC_RETURN_DOUBLE;
00949 DOUBLEVALUE(besRETURNVALUE) = DOUBLEVALUE((*p)->vV);
00950 besUnlockSharedRead(&((*p)->lckV));
00951 return COMMAND_ERROR_SUCCESS;
00952 }
00953
00954 return EXE_ERROR_INTERNAL;
00955 besEND
00956
01033 besFUNCTION(lockmtwrite)
01034 VARIABLE Argument;
01035 char *pszVariableName;
01036 pMTVariable *p;
01037 besRETURNVALUE = NULL;
01038
01039 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
01040
01041 Argument = besARGUMENT(1);
01042 besDEREFERENCE(Argument);
01043 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
01044 Argument = besCONVERT2STRING(Argument);
01045 besCONVERT2ZCHAR(Argument,pszVariableName);
01046
01047 besLockMutex(&mxMTVariables);
01048 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01049 besFREE(pszVariableName);
01050 if( p == NULL ){
01051 besUnlockMutex(&mxMTVariables);
01052 return COMMAND_ERROR_MEMORY_LOW;
01053 }
01054
01055 if( *p == NULL ){
01056 *p = besPROCALLOC(sizeof(MTVariable));
01057 if( *p == NULL ){
01058 besUnlockMutex(&mxMTVariables);
01059 return COMMAND_ERROR_MEMORY_LOW;
01060 }
01061 besInitSharedLock(&((*p)->lckV));
01062 (*p)->vV = NULL;
01063 }
01064 besUnlockMutex(&mxMTVariables);
01065
01066 besLockSharedWrite(&((*p)->lckV));
01067
01068 return COMMAND_ERROR_SUCCESS;
01069 besEND
01070
01081 besFUNCTION(lockmtread)
01082 VARIABLE Argument;
01083 char *pszVariableName;
01084 pMTVariable *p;
01085 besRETURNVALUE = NULL;
01086
01087 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
01088
01089 Argument = besARGUMENT(1);
01090 besDEREFERENCE(Argument);
01091 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
01092 Argument = besCONVERT2STRING(Argument);
01093 besCONVERT2ZCHAR(Argument,pszVariableName);
01094
01095 besLockMutex(&mxMTVariables);
01096 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01097 besFREE(pszVariableName);
01098 if( p == NULL ){
01099 besUnlockMutex(&mxMTVariables);
01100 return COMMAND_ERROR_MEMORY_LOW;
01101 }
01102
01103 if( *p == NULL ){
01104 *p = besPROCALLOC(sizeof(MTVariable));
01105 if( *p == NULL ){
01106 besUnlockMutex(&mxMTVariables);
01107 return COMMAND_ERROR_MEMORY_LOW;
01108 }
01109 besInitSharedLock(&((*p)->lckV));
01110 (*p)->vV = NULL;
01111 }
01112 besUnlockMutex(&mxMTVariables);
01113
01114 besLockSharedRead(&((*p)->lckV));
01115
01116 return COMMAND_ERROR_SUCCESS;
01117 besEND
01118
01125 besFUNCTION(unlockmtwrite)
01126 VARIABLE Argument;
01127 char *pszVariableName;
01128 pMTVariable *p;
01129 besRETURNVALUE = NULL;
01130
01131 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
01132
01133 Argument = besARGUMENT(1);
01134 besDEREFERENCE(Argument);
01135 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
01136 Argument = besCONVERT2STRING(Argument);
01137 besCONVERT2ZCHAR(Argument,pszVariableName);
01138
01139 besLockMutex(&mxMTVariables);
01140 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01141 besFREE(pszVariableName);
01142 if( p == NULL ){
01143 besUnlockMutex(&mxMTVariables);
01144 return COMMAND_ERROR_MEMORY_LOW;
01145 }
01146
01147 if( *p == NULL ){
01148 *p = besPROCALLOC(sizeof(MTVariable));
01149 if( *p == NULL ){
01150 besUnlockMutex(&mxMTVariables);
01151 return COMMAND_ERROR_MEMORY_LOW;
01152 }
01153 besInitSharedLock(&((*p)->lckV));
01154 (*p)->vV = NULL;
01155 return COMMAND_ERROR_SUCCESS;
01156 }
01157 besUnlockMutex(&mxMTVariables);
01158
01159 besUnlockSharedWrite(&((*p)->lckV));
01160
01161 return COMMAND_ERROR_SUCCESS;
01162 besEND
01163
01169 besFUNCTION(unlockmtread)
01170 VARIABLE Argument;
01171 char *pszVariableName;
01172 pMTVariable *p;
01173 besRETURNVALUE = NULL;
01174
01175 if( besARGNR < 1 )return COMMAND_ERROR_FEW_ARGS;
01176
01177 Argument = besARGUMENT(1);
01178 besDEREFERENCE(Argument);
01179 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
01180 Argument = besCONVERT2STRING(Argument);
01181 besCONVERT2ZCHAR(Argument,pszVariableName);
01182
01183 besLockMutex(&mxMTVariables);
01184 p = (pMTVariable *)pSt->LookupSymbol(pszVariableName,MtVariables,1,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01185 besFREE(pszVariableName);
01186 if( p == NULL ){
01187 besUnlockMutex(&mxMTVariables);
01188 return COMMAND_ERROR_MEMORY_LOW;
01189 }
01190
01191 if( *p == NULL ){
01192 *p = besPROCALLOC(sizeof(MTVariable));
01193 if( *p == NULL ){
01194 besUnlockMutex(&mxMTVariables);
01195 return COMMAND_ERROR_MEMORY_LOW;
01196 }
01197 besInitSharedLock(&((*p)->lckV));
01198 (*p)->vV = NULL;
01199 return COMMAND_ERROR_SUCCESS;
01200 }
01201 besUnlockMutex(&mxMTVariables);
01202
01203 besUnlockSharedRead(&((*p)->lckV));
01204
01205 return COMMAND_ERROR_SUCCESS;
01206 besEND
01207
01223 besFUNCTION(sessionto)
01224 VARIABLE Argument;
01225 pSessionInfo pS;
01226 pMtClass pMT;
01227
01228 besRETURNVALUE = NULL;
01229 pMT = besMODULEPOINTER;
01230 pS = pMT->AssignedSession;
01231
01232
01233 if( pS == NULL )return MT_ERROR_NOSESSION;
01234
01235
01236
01237 if( besARGNR < 1 ){
01238 pS->lTimeout = 0;
01239 return COMMAND_ERROR_SUCCESS;
01240 }
01241
01242 Argument = besARGUMENT(1);
01243 besDEREFERENCE(Argument);
01244
01245 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
01246 Argument = besCONVERT2LONG(Argument);
01247
01248 pS->lTimeout= time(NULL) + LONGVALUE(Argument);
01249
01250 return COMMAND_ERROR_SUCCESS;
01251 besEND
01252
01262 besFUNCTION(getsesto)
01263 char *pszSession;
01264 void **p;
01265 VARIABLE Argument;
01266 pSessionInfo pS;
01267 pMtClass pMT;
01268 int bSessDef;
01269
01270
01271 pMT = besMODULEPOINTER;
01272 pS = pMT->AssignedSession;
01273
01274 besRETURNVALUE = NULL;
01275
01276 Argument = besARGUMENT(1);
01277 besDEREFERENCE(Argument);
01278 if( Argument == NULL ){
01279 bSessDef = 1;
01280 pszSession = pMT->pszSessionId;
01281 if( pszSession == NULL )return MT_ERROR_NOSESSION;
01282 }else{
01283 bSessDef = 0;
01284 Argument = besCONVERT2STRING(Argument);
01285 besCONVERT2ZCHAR(Argument,pszSession);
01286 }
01287
01288 besLockMutex(&mxSessionTable);
01289 p = pSt->LookupSymbol(pszSession,SessionTable,0,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01290
01291
01292 if( p == NULL ){
01293 besUnlockMutex(&mxSessionTable);
01294 if( ! bSessDef )besFREE(pszSession);
01295 besRETURNVALUE = NULL;
01296 if( ! bSessDef )besFREE(pszSession);
01297 return COMMAND_ERROR_SUCCESS;
01298 }
01299
01300 pS = *p;
01301
01302 besUnlockMutex(&mxSessionTable);
01303
01304
01305 if( pS == NULL ){
01306
01307 if( ! bSessDef )besFREE(pszSession);
01308 besRETURNVALUE = NULL;
01309 if( ! bSessDef )besFREE(pszSession);
01310 return EXE_ERROR_INTERNAL;
01311 }
01312
01313 besALLOC_RETURN_LONG;
01314 LONGVALUE(besRETURNVALUE) = pS->lTimeout;
01315
01316
01317
01318 if( ! bSessDef )besFREE(pszSession);
01319 besEND
01320
01330 besFUNCTION(getsespt)
01331 char *pszSession;
01332 void **p;
01333 VARIABLE Argument;
01334 pSessionInfo pS;
01335 pMtClass pMT;
01336 int bSessDef;
01337
01338
01339 pMT = besMODULEPOINTER;
01340 pS = pMT->AssignedSession;
01341
01342 besRETURNVALUE = NULL;
01343
01344 Argument = besARGUMENT(1);
01345 besDEREFERENCE(Argument);
01346 if( Argument == NULL ){
01347 bSessDef = 1;
01348 pszSession = pMT->pszSessionId;
01349 if( pszSession == NULL )return MT_ERROR_NOSESSION;
01350 }else{
01351 bSessDef = 0;
01352 Argument = besCONVERT2STRING(Argument);
01353 besCONVERT2ZCHAR(Argument,pszSession);
01354 }
01355
01356 besLockMutex(&mxSessionTable);
01357 p = pSt->LookupSymbol(pszSession,SessionTable,0,pSt->Alloc,pSt->Free,besPROCMEMORYSEGMENT);
01358
01359
01360 if( p == NULL ){
01361 besUnlockMutex(&mxSessionTable);
01362 if( ! bSessDef )besFREE(pszSession);
01363 besRETURNVALUE = NULL;
01364 if( ! bSessDef )besFREE(pszSession);
01365 return COMMAND_ERROR_SUCCESS;
01366 }
01367
01368 pS = *p;
01369
01370 besUnlockMutex(&mxSessionTable);
01371
01372
01373 if( pS == NULL ){
01374
01375 if( ! bSessDef )besFREE(pszSession);
01376 besRETURNVALUE = NULL;
01377 if( ! bSessDef )besFREE(pszSession);
01378 return EXE_ERROR_INTERNAL;
01379 }
01380
01381 besALLOC_RETURN_LONG;
01382 LONGVALUE(besRETURNVALUE) = pS->lPingTime;
01383
01384
01385
01386 if( ! bSessDef )besFREE(pszSession);
01387 besEND
01388
01447 besFUNCTION(listses)
01448 VARIABLE Argument,*Lval;
01449 long cSessionList;
01450 pSessionInfo pS;
01451
01452 unsigned long lToMin,lToMax,lPtMin,lPtMax,lStMin,lStMax;
01453 int iError;
01454 long __refcount_;
01455
01456 Argument = besARGUMENT(1);
01457 besLEFTVALUE(Argument,Lval);
01458 if( ! Lval )return COMMAND_ERROR_ARGUMENT_TYPE;
01459 besRELEASE(*Lval);
01460 iError = besGETARGS "*[iiiiii]" , &lStMin, &lStMax, &lPtMin, &lPtMax, &lToMin, &lToMax besGETARGE
01461
01462 if( iError )return iError;
01463
01464 #define SESSION__CONSTRAINT \
01465 ( lToMin < pS->lTimeout ) && \
01466 ( lPtMin < pS->lPingTime) && \
01467 ( lStMin < pS->lTimeStart) &&\
01468 ( (!lToMax) || lToMax > pS->lTimeout) && \
01469 ( (!lPtMax) || lPtMax > pS->lPingTime) && \
01470 ( (!lStMax) || lStMax > pS->lTimeStart)
01471
01472 pS = pSessionRoot;
01473 cSessionList = 0;
01474 besLockMutex(&mxSessionTable);
01475 while( pS ){
01476 if( SESSION__CONSTRAINT )cSessionList ++;
01477 pS = pS->next;
01478 }
01479
01480 if( cSessionList == 0 ){
01481 *Lval = NULL;
01482 besUnlockMutex(&mxSessionTable);
01483 return COMMAND_ERROR_SUCCESS;
01484 }
01485 *Lval = besNEWARRAY(1,cSessionList);
01486 if( *Lval == NULL ){
01487 besUnlockMutex(&mxSessionTable);
01488 return COMMAND_ERROR_MEMORY_LOW;
01489 }
01490
01491 pS = pSessionRoot;
01492 cSessionList = 0;
01493 while( pS ){
01494 if( SESSION__CONSTRAINT ){
01495 (*Lval)->Value.aValue[cSessionList] = besNEWSTRING(strlen(pS->pszId));
01496 if( (*Lval)->Value.aValue[cSessionList] == NULL ){
01497 besUnlockMutex(&mxSessionTable);
01498 return COMMAND_ERROR_MEMORY_LOW;
01499 }
01500 memcpy(STRINGVALUE((*Lval)->Value.aValue[cSessionList]),pS->pszId,strlen(pS->pszId));
01501 cSessionList ++;
01502 }
01503 pS = pS->next;
01504 }
01505
01506 besUnlockMutex(&mxSessionTable);
01507
01508
01509 besEND
01510
01511
01512 besVERSION_NEGOTIATE
01513
01514 return (int)INTERFACE_VERSION;
01515
01516 besEND
01517
01518
01519 besSUB_FINISH
01520 pSessionInfo pS;
01521 pMtClass pMT;
01522
01523 pMT = besMODULEPOINTER;
01524 pS = pMT->AssignedSession;
01525
01526
01527
01528 DEC_THREAD_COUNTER
01529
01530
01531 if( pS )besUnlockSharedRead(&(pS->lckSession));
01532
01533 besEND
01534
01535 besDLL_MAIN
01536
01537
01538
01539
01540
01541 besSUB_KEEP
01542 long lTC;
01543
01544
01545
01546 GET_THREAD_COUNTER(lTC);
01547
01548
01549 if( lTC == 0 ){
01550 INC_THREAD_COUNTER
01551 }
01552
01553 return lTC ? 1 : 0;
01554 besEND
01555
01556 besSUB_PROCESS_START
01557 INIT_MULTITHREAD
01558 return 1;
01559 besEND
01560
01561 besSUB_PROCESS_FINISH
01562 FINISH_MULTITHREAD
01563 besEND
01564
01565 SLFST MT_SLFST[] ={
01566
01567 { "keepmodu" , keepmodu },
01568 { "shutmodu" , shutmodu },
01569 { "bootmodu" , bootmodu },
01570 { "setsession" , setsession },
01571 { "chksession" , chksession },
01572 { "sessioncount" , sessioncount },
01573 { "newsession" , newsession },
01574 { "delsession" , delsession },
01575 { "getsession" , getsession },
01576 { "setsvariable" , setsvariable },
01577 { "getsvariable" , getsvariable },
01578 { "setmtvariable" , setmtvariable },
01579 { "getmtvariable" , getmtvariable },
01580 { "lockmtwrite" , lockmtwrite },
01581 { "lockmtread" , lockmtread },
01582 { "unlockmtwrite" , unlockmtwrite },
01583 { "unlockmtread" , unlockmtread },
01584 { "sessionto" , sessionto },
01585 { "getsesto" , getsesto },
01586 { "getsespt" , getsespt },
01587 { "listses" , listses },
01588 { "versmodu" , versmodu },
01589 { "finimodu" , finimodu },
01590 { "keepmodu" , keepmodu },
01591 { "_init" , _init },
01592 { "_fini" , _fini },
01593 { NULL , NULL }
01594 };