0
votes

I'm programming in C using win32 api.
My program starts at void main , I do some action that create mutex with specific name and then launching waitForSingleObject function on it with INFINITE time parameter.

Then I'm launching an EXE process by createProcess function.
The EXE process has a similar code that is now doing createMutex with the same name I did before with the parent process.

As I understand I should get a handle to the same mutex I created in the parent program.. because it has the same name. So after that, the EXE code is also doing again WaitForSingleObject on the mutex handle with same parameters.

I have expected this to stop and wait now but it continued as it was signaled somehow, but there is no way I did a signal anywhere at this stage.
I tried to replace the INFINITE parameter with 0 and to see if I get WAIT_TIMEOUT but this didn't work also.
Why my mutex don't work?

Thanks

relevant code added: (I tried to put only things that are relevant) * please note the the EXE file Process1 contains a code that does openfileInDirectory with the same file name I did in void main and for write. ** My mutex to follow is that is called writeMutex. FileSystemMutex is another one that has nothing to do with my current problem.

// Global variables definition from library header
void* viewVec;
HANDLE fileHandle;
int directoryLastBlockIndex;
FilesInProcessUse processFiles;          
HANDLE fileSystemMutex;
HANDLE filesAccessSemaphore;

void main()
{         

    FileDescriptor* fd, *fd2;
    int message,message2,message3;
    int processId = GetCurrentProcessId();
    char* input= NULL;

    /* print out our process ID */
    printf("Process %d reporting for duty\n",processId);


    fileSystemMutex = CreateMutex(NULL,FALSE,FILE_SYSTEM_MUTEX_NAME);
    printf("Process %d: After creating fileSystem mutex\n",processId);
    filesAccessSemaphore = CreateSemaphore(NULL,MAX_ACCESSORS_FOR_ALL_FILES,MAX_ACCESSORS_FOR_ALL_FILES,FILE_SYSTEM_SEMAPHORE_NAME);
    printf("Process %d: After creating filesAccessSemaphore\n",processId);

    initfs("C",NUM_OF_BLOCKS_IN_DISK,NUM_OF_BLOCKS_IN_DISK);

    viewVec = attachfs("C"); // Saving the address of the vector in global pointer.  

    if(viewVec!=NULL)
    {
        printf("Process %d: After AttachFS which succeded\n",processId);
        fd = (FileDescriptor*) createFileInDirectory("FileX",2,&message);
        if (fd!=NULL)
        {
            printf("Process %d:successfuly created the file: FileX in Drive C\n",processId);
        }
        else
        {
            printErrMessage(message);
        }
    }
    else
    {
        printf("Process %d: After AttachFS, which failed\n",processId);
    }

    fd = (FileDescriptor*) openFileInDirectory("FileX",READ_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileXfile for read succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }
    closeFileInDirectory(fd);
    fd = (FileDescriptor*) openFileInDirectory("FileX",WRITE_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileXfile for write succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }

    fd2 = (FileDescriptor*) openFileInDirectory("FileX",WRITE_PERMISSION,&message);
    if(fd!=NULL)
    {
        printf("Process %d: opened FileX file for write succefully",processId);
    }
    else
    {
        printf("Process %d:",processId);
        printErrMessage(message);
    }
}
}


void* openFileInDirectory(char* fileName, int ReadWriteFlag, int* out_ErrMessage)
{

    SystemInfoSection* sysInfo = readSystemInformationFromBeginingOfVector((char*)viewVec);
    DirectoryEntry* fileEntryInDirOffset;
    FileDescriptor* openfileDescriptor = NULL;
    int fileIndexInOpenFiles = 0;
    int writeRV;

    //Mark that another file is being processed 
    WaitForSingleObject(filesAccessSemaphore,INFINITE);


    //Check if the file exists else return error
    if(isFileAlreadyExisting(fileName, sysInfo->directoryStartBlockIndex, &fileEntryInDirOffset))
    {
        fileIndexInOpenFiles = getFileIndexInOpenFileDirectory(fileName);
        processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore = CreateSemaphore(NULL,MAX_FILE_ACCESSORS,MAX_FILE_ACCESSORS,fileName);
        WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore,INFINITE);
        if (ReadWriteFlag == WRITE_PERMISSION)
        {
            char writeMutexName[15];
            strcpy(writeMutexName, WRITE_MUTEX_PREFIX);
            strcat(writeMutexName, fileName);
            processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex = CreateMutex(NULL,FALSE,writeMutexName);

            WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex,INFINITE);

            //writeRV = WaitForSingleObject(processFiles.allFilesVector[fileIndexInOpenFiles].writeMutex,MAX_WAIT_TIMEOUT_IN_FS);
            //if(writeRV == WAIT_TIMEOUT)
            //{
            //  ReleaseSemaphore(processFiles.allFilesVector[fileIndexInOpenFiles].accessSemaphore,1,NULL);
            //  //return error indicating that another process is already writing to the file AND RETURN FROM THE FUNCTION
            //  *out_ErrMessage = ERR_FILE_IS_ALREADY_OPEN_TO_A_WRITE_BY_SOME_PROCESS;
            //  return openfileDescriptor;

            //}
        }

        processFiles.FDInProcessUseVector[fileIndexInOpenFiles].fileDirectoryEntry = fileEntryInDirOffset;
        processFiles.FDInProcessUseVector[fileIndexInOpenFiles].readWriteFlag = ReadWriteFlag;
        openfileDescriptor = &(processFiles.FDInProcessUseVector[fileIndexInOpenFiles]);
        processFiles.numOfFilesInUse++;


    }

    else
    {
        openfileDescriptor = NULL;
        *out_ErrMessage = ERR_FILE_NOT_FOUND;
    }
    free(sysInfo);

    return openfileDescriptor;
}
1
@ keith Nicholas: thanks for your comment code added, I could add much more but I think it is now sufficient - JavaSa
Are you getting ERROR_ALREADY_EXISTS as expected? - Ben Voigt
From your description, the first process will never wait as there is nothing to wait on... - Deanna
On the first time I do createMutex I get FILE_NOT_FOUND on the second time I get ACCESS_DENIED- but this is when I'm trying to do twice open for write from the same single process, because I cannot debug EXE file unless I will plant some prinfs there - JavaSa
You say you are using a mutex but the code you posted is using a semaphore (I guess - there is no mutex named writeMutex and you told us to ignore fileSystemMutex). The reason your wait succeeds on the semaphore is that it is available. You have set the second parameter of CreateSemaphore to MAX_ACCESSORS_FOR_ALL_FILES. You should reduce your code to the minimum that compiles and exhibits the problem. - tinman

1 Answers

4
votes

You can use CreateMutex function to create named global mutex.

Logic of using global mutex is usually following:

  1. You try to create mutex by using CreateMutex. Note that "If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object".
  2. You lock (get ownership) by using WaitForSingleObject function
  3. You unlock (release ownership) by using ReleaseMutex function
  4. You CloseHandle returned by CreateMutex function.

Here is good example in C: Using Mutex Objects

There are few problems in your code:

  1. You don't release ownership of writeMutex, which is probably the main reason why this code can't work.
  2. You don't check the return value of a single call. The only return value that you check is the one returned from your function. Check documentation of these functions so that you can handle possible error states properly.
  3. You don't CloseHandle returned by CreateMutex function. Neither handle of fileSystemMutex nor handle of writeMutex.
  4. You create fileSystemMutex, but then you never use it. This mutex has no sense there.