windows-tests-torture-20090405
[openafs.git] / src / WINNT / tests / torture / Source / WinThreads.c
1 #include <windows.h>
2 #include <stdlib.h>
3 #include "includes.h"
4 #include "common.h"
5 #ifdef HAVE_HESOID
6     #include "ResolveLocker.h"
7     int ResolveLocker(USER_OPTIONS *attachOption);
8 #endif
9 #ifndef NO_AFS_SOURCE
10     #include <afs\stds.h>
11     #include <afs\smb_iocons.h>
12     #include <afs\afsint.h>
13     #include <afs\pioctl_nt.h>
14 #else
15     #define VIOCGETVOLSTAT  0x7
16     #define afs_int32   int
17
18     struct VolumeStatus {
19             afs_int32 Vid;
20             afs_int32 ParentId;
21             char Online;
22             char InService;
23             char Blessed;
24             char NeedsSalvage;
25             afs_int32 Type;
26             afs_int32 MinQuota;
27             afs_int32 MaxQuota;
28             afs_int32 BlocksInUse;
29             afs_int32 PartBlocksAvail;
30             afs_int32 PartMaxBlocks;
31     };
32
33     typedef struct VolumeStatus VolumeStatus;
34
35     typedef struct ViceIoctl {
36             long in_size;
37             long out_size;
38             void *in;
39             void *out;
40     } viceIoctl_t;
41 extern long pioctl(char *pathp, long opcode, struct ViceIoctl *blob, int follow);
42 #endif
43
44 #define MAX_PARAMS 20
45 #define ival(s) strtol(s, NULL, 0)
46 #define AFSDLL "afsauthent.dll"
47
48 #define WINTORTURE_ASFDLL_ONLINE        1
49 #define WINTORTURE_ASFDLL_OFFLINE       2
50 #define WINTORTURE_ASFDLL_NOTFOUND      3
51 #define WINTORTURE_ASFPIOCTL_NOTFOUND   4
52
53 extern int verbose;
54
55 extern void EndSecondTime(int cmd);
56 extern void StartSecondTime(int cmd);
57 extern void LogMessage(int ProcessNumber, char *HostName, char *FileName, char *message, int LogID);
58 extern void LogStats(char *FileName, int ToLog, int Iteration,  int NumberOfProcesses, int NumberOfThreads,
59                      char *HostName, int ProcessNumber, struct cmd_struct ThreadCommandInfo[],
60                      char *CommandLine, char *TargetDirectory);
61 extern void SubstituteString(char *s,const char *pattern,const char *insert, size_t len);
62
63 int  IsOnline(char *strPath);
64 BOOL run_netbench(int client, char *ClientTxt, char *PathToSecondDir);
65
66 HANDLE  MutexHandle;
67 HANDLE  FileMutexHandle;
68 HANDLE  ShutDownEventHandle;
69 HANDLE  PauseEventHandle;
70 HANDLE  ContinueEventHandle;
71 HANDLE  OSMutexHandle;
72
73 __declspec( thread ) int    AfsTrace;
74 __declspec( thread ) int    CurrentLoop;
75 __declspec( thread ) int    ProcessNumber = 0;
76 __declspec( thread ) int    LogID = 0;
77 __declspec( thread ) int    LineCount = 0;
78 __declspec( thread ) int    *pThreadStatus;
79 __declspec( thread ) DWORD  TickCount1,TickCount2, MilliTickStart;
80 __declspec( thread ) int    BufferSize = 4096;
81 __declspec( thread ) char   *IoBuffer = NULL;
82 __declspec( thread ) char   AfsLocker[256];
83 __declspec( thread ) char   OriginalAfsLocker[256];
84 __declspec( thread ) char   HostName[256];
85 __declspec( thread ) struct cmd_struct ThreadCommandInfo[CMD_MAX_CMD + 1];
86 __declspec( thread ) FTABLE ftable[MAX_FILES];
87 __declspec( thread ) HANDLE hWinEventHandle;
88 __declspec( thread ) EXIT_STATUS *pExitStatus;
89 __declspec( thread ) DWORD  LastKnownError;
90
91
92 DWORD WINAPI StressTestThread(LPVOID lpThreadParameter)
93 {
94     int         j;
95     int         rc;
96     size_t      count;
97     int         ProcessID;
98     char        EventName[64];
99     char        FileName[256];
100     char        CommandLine[512];
101     char        TargetDirectory[512];
102     char        WorkingDirectory[512];
103     char        ClientText[128];
104     char        PathToSecondDir[256];
105     char        temp[512];
106     BOOL        PrintStats;
107     PARAMETERLIST *pParameterList;
108     struct cmd_struct *WinCommandInfo;
109
110     pParameterList = (PARAMETERLIST *)lpThreadParameter;
111     pThreadStatus = pParameterList->pThreadStatus;
112     BufferSize = pParameterList->BufferSize;
113     ProcessNumber = pParameterList->ProcessNumber;
114     PrintStats = pParameterList->PrintStats;
115     CurrentLoop = pParameterList->CurrentLoop;
116     ProcessID = pParameterList->ProcessID;
117     LogID = pParameterList->LogID;
118     AfsTrace = pParameterList->AfsTrace;
119     pExitStatus = pParameterList->pExitStatus;
120     strcpy(TargetDirectory, pParameterList->TargetDirectory);
121     strcpy(CommandLine, pParameterList->CommandLine);
122     strcpy(ClientText, pParameterList->ClientText);
123     strcpy(PathToSecondDir, pParameterList->PathToSecondDir);
124     strcpy(AfsLocker, pParameterList->AfsLocker);
125     strcpy(HostName, pParameterList->HostName);
126     WinCommandInfo = ( struct cmd_struct *)pParameterList->CommandInfo;
127
128     sprintf(EventName, "%d%sEvent%05d", ProcessID, HostName, ProcessNumber);
129     hWinEventHandle = OpenEvent(EVENT_ALL_ACCESS, TRUE, EventName);
130
131     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
132     GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
133     sprintf(temp, "%s\\log%05d\\%s", WorkingDirectory, LogID, HostName);
134     CreateDirectory(temp, NULL);
135
136
137     memset(ftable, '\0', sizeof(ftable[0]) * MAX_FILES);
138     IoBuffer = malloc(BufferSize);
139     if (!IoBuffer)
140     {
141         strcpy(pExitStatus->Reason, "Unable to allocate buffer");
142         pExitStatus->ExitStatus = 1;
143         SetEvent(hWinEventHandle);
144         ExitThread(1);
145     }
146     memset(IoBuffer, (unsigned char)getpid(), BufferSize);
147
148     ShutDownEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsShutdownEvent");
149     PauseEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsPauseEvent");
150     ContinueEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsContinueEvent");
151     OSMutexHandle = CreateMutex(NULL, FALSE, "WinTortureOSMutex");
152     MutexHandle = CreateMutex(NULL, FALSE, "WinTortureMutex");
153
154     strcpy(OriginalAfsLocker, AfsLocker);
155
156     while (1)
157     {
158         LastKnownError = 0;
159         for (j = 0; j <= CMD_MAX_CMD; j++)
160         {
161             WinCommandInfo[j].count = 0;
162             WinCommandInfo[j].min_sec = 0;
163             WinCommandInfo[j].max_sec = 0;
164             WinCommandInfo[j].MilliSeconds = 0;
165             WinCommandInfo[j].total_sec = 0;
166             WinCommandInfo[j].total_sum_of_squares = 0;
167             WinCommandInfo[j].ErrorCount = 0;
168             WinCommandInfo[j].ErrorTime = 0;
169             ThreadCommandInfo[j].count = 0;
170             ThreadCommandInfo[j].min_sec = 1000;
171             ThreadCommandInfo[j].max_sec = 0;
172             ThreadCommandInfo[j].MilliSeconds = 0;
173             ThreadCommandInfo[j].total_sec = 0;
174             ThreadCommandInfo[j].total_sum_of_squares = 0;
175             ThreadCommandInfo[j].ErrorCount = 0;
176             ThreadCommandInfo[j].ErrorTime = 0;
177         }
178
179         run_netbench(ProcessNumber, ClientText, PathToSecondDir);
180         if (LastKnownError != ERROR_NETNAME_DELETED)
181             break; 
182         sprintf(temp, "entered error %d processing\n", LastKnownError);
183         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
184
185         count = strlen(pExitStatus->Reason);
186         if (count != 0)
187             memset(pExitStatus->Reason, '\0', count);
188         pExitStatus->ExitStatus = 0;
189         (*pThreadStatus) = 1;
190         count = 0;
191         
192         while ((rc = IsOnline(OriginalAfsLocker)) != WINTORTURE_ASFDLL_ONLINE)
193         {
194             if ((count > 3) || (rc == WINTORTURE_ASFDLL_NOTFOUND) || (rc == WINTORTURE_ASFPIOCTL_NOTFOUND))
195             {
196                 LastKnownError = 0;
197                 sprintf(temp, "AFS path \"%s\" appears to be off-line\n", OriginalAfsLocker);
198                 strcpy(pExitStatus->Reason, temp);
199                 pExitStatus->ExitStatus = 1;
200                 (*pThreadStatus) = 0;
201                 printf("%s", temp);
202                 LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
203                 strcpy(temp, "Stress test is terminating\n");
204                 printf(temp);
205                 LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
206                 break;
207             }
208             sprintf(temp, "AFS path \"%s\" is online, sleeping 10 seconds before continuing\n", OriginalAfsLocker);
209             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
210             ++count;
211             Sleep(10 * 1000);
212         }
213         sprintf(temp, "leaving error 0x%x processing\n", LastKnownError);
214         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
215         if (count > 3)
216             break;
217     }
218     free(IoBuffer);
219
220     for (j = 0; j <= CMD_MAX_CMD; j++)
221     {
222         WinCommandInfo[j].count += ThreadCommandInfo[j].count;
223         WinCommandInfo[j].min_sec += ThreadCommandInfo[j].min_sec;
224         WinCommandInfo[j].max_sec += ThreadCommandInfo[j].max_sec;
225         WinCommandInfo[j].total_sec += ThreadCommandInfo[j].total_sec;
226         WinCommandInfo[j].total_sum_of_squares += ThreadCommandInfo[j].total_sum_of_squares;
227         WinCommandInfo[j].ErrorCount += ThreadCommandInfo[j].ErrorCount;
228         WinCommandInfo[j].ErrorTime += ThreadCommandInfo[j].ErrorTime;
229     }
230
231     memset(WorkingDirectory, '\0', sizeof(WorkingDirectory));
232     GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
233     sprintf(FileName, "%s\\log%05d\\%s\\Thread_%05d_Stats.log", WorkingDirectory, LogID, HostName, ProcessNumber);
234
235     if (PrintStats)
236     {
237         WaitForSingleObject(MutexHandle, 4 * 1000);
238         LogStats(FileName, 0, CurrentLoop, 0, 0, HostName, ProcessNumber, ThreadCommandInfo, CommandLine, TargetDirectory);
239         ReleaseMutex(MutexHandle);
240     }
241
242     LogStats(FileName, 1, CurrentLoop, 0, 0, HostName, ProcessNumber, ThreadCommandInfo,CommandLine, TargetDirectory);
243
244     SetEvent(hWinEventHandle);
245     CloseHandle(hWinEventHandle);
246 //    CloseHandle(OSMutexHandle);
247 //    CloseHandle(MutexHandle);
248
249     ExitThread(0);
250     return(0);
251 }
252
253 BOOL run_netbench(int client, char *ClientText, char *PathToSecondDir)
254 {
255     pstring line;
256     pstring line1;
257     char    cname[20];
258     char    *params[MAX_PARAMS];
259     char    temp[256];
260     char    FileName[256];
261     char    *pPtr;
262     int     rc;
263     int     i;
264     int     IncreaseBy;
265     BOOL    correct = TRUE;
266     DWORD   dwFlags = 0;
267     DWORD   NumberOfBytes;
268     DWORD   TotalBytesRead;
269     HANDLE  hFile;
270     enum    states bm_state;
271     CRITICAL_SECTION CriticalSection;
272
273
274     InitializeCriticalSection(&CriticalSection);
275
276     sprintf(cname, "client%d", client);
277
278     sprintf(temp, "Started Iteration %d\n", CurrentLoop);
279     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
280     LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
281     sprintf(temp, "Thread %d started\n", ProcessNumber);
282     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
283     LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
284
285     hFile = CreateFile(ClientText, GENERIC_READ | STANDARD_RIGHTS_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
286
287     if (hFile == INVALID_HANDLE_VALUE) 
288     {
289         perror(ClientText);
290         return(-1);
291     }
292
293     StartSecondTime(CMD_NONAFS);
294     TotalBytesRead = 0;
295     while (1)
296     {
297         memset(line, '\0', sizeof(line));
298         NumberOfBytes = 0;
299         rc = ReadFile(hFile, line, 128, &NumberOfBytes, NULL);
300         if (rc && NumberOfBytes == 0)
301             break;
302         pPtr = strchr(line, '\n');
303         IncreaseBy = 0;
304         if (pPtr != NULL)
305         {
306             IncreaseBy += 1;
307             (*pPtr) = '\0';
308             if ((*(pPtr - 1)) == '\r')
309             {
310                 IncreaseBy += 1;
311                 (*(pPtr - 1)) = '\0';
312             }
313         }
314         TotalBytesRead += (DWORD)(strlen(line) + IncreaseBy);
315         SetFilePointer(hFile, TotalBytesRead, 0, FILE_BEGIN);
316         strcpy(line1, line);
317         if (rc = WaitForSingleObject(PauseEventHandle, 0) == WAIT_OBJECT_0)
318         {
319             strcpy(temp, "AFS suspend request received\n");
320             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
321             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
322             while (WaitForSingleObject(ContinueEventHandle, 5000) == WAIT_TIMEOUT);
323             strcpy(temp, "AFS continue request received\n");
324             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
325             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
326         }
327         if (rc = WaitForSingleObject(ShutDownEventHandle, 0) == WAIT_OBJECT_0)
328         {
329             strcpy(temp, "AFS shutdown request received\n");
330             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
331             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
332             break;
333         }
334         LineCount++;
335         if (strlen(line) == 0)
336             continue;
337         if (line[0] == '#')
338             continue;
339         /*printf("[%d] %s\n", LineCount, line);*/
340
341         for (i = 0; i < MAX_PARAMS; i++)
342             params[i] = NULL;
343
344         SubstituteString(line,"client1", cname, sizeof(line));
345         sprintf(temp, "%s%05d", HostName, LogID);
346         SubstituteString(line,"clients", temp, sizeof(line));
347         SubstituteString(line,"\\\\afs\\locker", AfsLocker, sizeof(line));
348         if (strlen(PathToSecondDir) != 0)
349                 SubstituteString(line,"\\\\afs\\lcolby", PathToSecondDir, sizeof(line));
350
351         if (verbose)
352         {
353             EnterCriticalSection(&CriticalSection);
354             printf("Thread%05d - %-6d - %s\n", ProcessNumber, LineCount, line);
355             LeaveCriticalSection(&CriticalSection);
356         }
357
358         pPtr = line;
359         i = 0;
360         while (pPtr != NULL)
361         {
362             if ((*pPtr) == ' ')
363             {
364                 (*pPtr) = '\0';
365                 ++pPtr;
366                 continue;
367             }
368             params[i] = pPtr;
369             ++i;
370             pPtr = strstr(pPtr, " ");
371             if (pPtr != NULL)
372             {
373                 (*pPtr) = '\0';
374                 ++pPtr;
375             }
376             
377         }
378
379         params[i] = "";
380
381         if (i < 1) 
382             continue;
383
384         if (!strncmp(params[0],"SMB", 3)) 
385         {
386             printf("ERROR: You are using a dbench 1 load file\n");
387             if (GetHandleInformation((HANDLE)hWinEventHandle, &dwFlags))
388                 break;
389         }
390         if (!strcmp(params[0], "BM_SETUP"))
391         {
392             bm_state = BM_SETUP;
393         } 
394         else if (!strcmp(params[0], "BM_WARMUP"))
395         {
396             bm_state = BM_WARMUP;
397         } 
398         else if (!strcmp(params[0], "BM_MEASURE"))
399         {
400             bm_state = BM_MEASURE;
401             if (verbose)
402                 fprintf(stderr, "setting state to BM_MEASURE\n");
403         } 
404         else if (!strcmp(params[0],"RECONNECT")) 
405         {
406             if (verbose)
407                 fprintf(stderr, "Reconnecting ...\n");
408         } 
409         else if (!strcmp(params[0], "SYNC"))
410         {
411             int length = atoi(params[1]), st = 0;
412             if (verbose)
413                 fprintf(stderr, "Syncing for %d seconds\n", length);
414         } 
415         else if (!strcmp(params[0],"NTCreateX")) 
416         {
417             if (nb_createx(params[1], ival(params[2]), ival(params[3]), ival(params[4])) == -1)
418                 break;
419         } 
420         else if (!stricmp(params[0],"SetLocker"))
421         {
422             if (nb_SetLocker(params[1]) == -1)
423                 break;
424         } 
425         else if (!stricmp(params[0],"Xrmdir")) 
426         {
427             if (nb_Xrmdir(params[1], params[2]) == -1)
428                 break;
429         } 
430         else if (!stricmp(params[0],"Mkdir")) 
431         {
432             if (nb_Mkdir(params[1]) == -1)
433                 break;
434         } 
435         else if (!stricmp(params[0],"Attach")) 
436         {
437             if (nb_Attach(params[1], params[2]) == -1)
438                 break;
439         } 
440         else if (!stricmp(params[0],"Detach")) 
441         {
442             if (nb_Detach(params[1], params[2]) == -1)
443                 break;
444         } 
445         else if (!stricmp(params[0],"CreateFile")) 
446         {
447             if (nb_CreateFile(params[1], atol(params[2])) == -1)
448                 break;
449         } 
450         else if (!stricmp(params[0],"CopyFiles")) 
451         {
452             if (nb_CopyFile(params[1], params[2]) == -1)
453                 break;
454         } 
455         else if (!stricmp(params[0],"DeleteFiles")) 
456         {
457             if (nb_DeleteFile(params[1]) == -1)
458                 break;
459         } 
460         else if (!stricmp(params[0],"Move")) 
461         {
462             if (nb_Move(params[1], params[2]) == -1)
463                 break;
464         } 
465         else if (!stricmp(params[0],"Xcopy")) 
466         {
467             if (nb_xcopy(params[1], params[2]) == -1)
468                 break;
469         } 
470         else if (!strcmp(params[0],"Close")) 
471         {
472             if (nb_close(ival(params[1])) == -1)
473                 break;
474         } 
475         else if (!strcmp(params[0],"Rename")) 
476         {
477             if (nb_rename(params[1], params[2]) == -1)
478                 break;
479         } 
480         else if (!strcmp(params[0],"Unlink")) 
481         {
482             if (nb_unlink(params[1]) == -1)
483                 break;
484         } 
485         else if (!strcmp(params[0],"Deltree"))
486         {
487             if (nb_deltree(params[1]) == -1)
488                 break;
489         } 
490         else if (!strcmp(params[0],"Rmdir")) 
491         {
492             if (nb_rmdir(params[1]) == -1)
493                 break;
494         } 
495         else if (!strcmp(params[0],"QUERY_PATH_INFORMATION"))
496         {
497             if (nb_qpathinfo(params[1], ival(params[2])) == -1)
498                 break;
499         } 
500         else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) 
501         {
502             if (nb_qfileinfo(ival(params[1])) == -1)
503                 break;
504         } 
505         else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) 
506         {
507             if (nb_qfsinfo(ival(params[1])) == -1)
508                 break;
509         } 
510         else if (!strcmp(params[0],"FIND_FIRST")) 
511         {
512             if (nb_findfirst(params[1]) == -1)
513                 break;
514         } 
515         else if (!strcmp(params[0],"WriteX")) 
516         {
517             if (nb_writex(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4])) == -1)
518                 break;
519         } 
520         else if (!strcmp(params[0],"ReadX")) 
521         {
522             if (nb_readx(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4])) == -1)
523                 break;
524         } 
525         else if (!strcmp(params[0],"Flush")) 
526         {
527             if (nb_flush(ival(params[1])) == -1)
528                 break;
529         } 
530         else if (!strcmp(params[0],"LockingX")) 
531         {
532             if (nb_lock(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4]),
533                         (unsigned char)ival(params[5]), ival(params[6])) == -1)
534                 break;
535         } 
536         else 
537         {
538             printf("Unknown operation %s\n", params[0]);
539             printf("Line read = %s\n", line1);
540             break;
541         }
542     }
543     CloseHandle(hFile);
544
545 //    nb_cleanup(cname);
546
547     EndSecondTime(CMD_NONAFS);
548
549     for (i = 0; i < MAX_FILES; i++) 
550     {
551         if (ftable[i].handle > 0)
552             nb_close(ftable[i].handle);
553     }
554
555         DeleteCriticalSection(&CriticalSection);
556
557     return(correct);
558 }
559
560 typedef long ( __cdecl  *PPIOCTL)(char *pathp, long opcode, struct ViceIoctl *blobp, int follow);
561
562 int IsOnline(char *strPath)
563 {
564     int     bret;
565     char    space[2048];
566     int     code;
567     int     rc;
568     struct  ViceIoctl blob;
569     struct  VolumeStatus *status;
570     static PPIOCTL ppioctl = NULL;
571     static HINSTANCE hAfsDll = NULL;
572
573     rc = WaitForSingleObject(OSMutexHandle, 5 * 1000);
574     bret = FALSE;
575     if (hAfsDll == NULL)
576         hAfsDll = LoadLibrary(AFSDLL);
577     if (hAfsDll)
578     {
579         if (ppioctl == NULL)
580             ppioctl = (PPIOCTL)GetProcAddress(hAfsDll, "pioctl");
581         if (ppioctl != NULL)
582         {
583             blob.in_size = 0;
584             blob.out_size = sizeof(space);
585             blob.out = space;
586 #if 0
587             if (!(code = ppioctl(strPath, VIOCGETVOLSTAT, &blob, 1)))
588             {
589                 bret = WINTORTURE_ASFDLL_ONLINE;
590                 status = (VolumeStatus *)space;
591                 if (!status->Online || !status->InService || !status->Blessed || status->NeedsSalvage)
592                     bret = WINTORTURE_ASFDLL_OFFLINE;
593             }
594 #else
595             errno = 0;
596             code = ppioctl(strPath, VIOC_PATH_AVAILABILITY, &blob, 1);
597             if (!code) {
598                 switch (errno) {
599                 case ENXIO:
600                 case ENOSYS:
601                 case EBUSY:
602                     bret = WINTORTURE_ASFDLL_OFFLINE;
603                     break;
604                 default:
605                     bret = WINTORTURE_ASFDLL_ONLINE;
606                     break;
607                 }
608             }
609 #endif 
610         }
611         else
612             bret = WINTORTURE_ASFPIOCTL_NOTFOUND;
613     }
614     else
615         bret = WINTORTURE_ASFDLL_NOTFOUND;
616
617     if (rc == WAIT_OBJECT_0)
618         ReleaseMutex(OSMutexHandle);
619
620     return(bret);
621 }
622