Solved

Locking a File

Posted on 2004-03-25
10
305 Views
Last Modified: 2011-09-20
I have a program that will be run via RF connection.  There will be multiple handhelds running this program, which means that one computer will be running multiple instances of the program.  The problem is that I need to be able to lock a file and make the other instances wait until the file is unlocked.

I am using one file (call it GLOBAL.TXT) and this file will be read from and written too by multiple instances of 2 different programs.  Can someone start me off on how to lock the file and make the other files wait there turn?  Sometype of a empty loop that runs until the file is unlocked?

Thanks for any help.
Jordan Marshall
0
Comment
Question by:Intern
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
10 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 10681134
Open file in exclusive mode.
0
 
LVL 1

Author Comment

by:Intern
ID: 10681310
Will that make the other programs wait?  or will they fail?  

"exclusive mode" - as in  file.open("GLOBAL.TXT", "something")

or am I off?  if not can you fill me in on the "something" part
0
 
LVL 16

Expert Comment

by:imladris
ID: 10681511
If you open a file in write mode, it will be in exclusive mode by default. Other open calls will fail. You could add a loop to the open code that will repeatedly attempt to open the file until it succeeds. It would probably be wise to wait a little bit between open attempts. Something like, in psuedo code:

do
{    attempt to open file
      if failed, wait a bit
} while(file open failure)

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Expert Comment

by:GJanusz
ID: 10682335
You can do this with fopen(), but I will assume you are using MFC's CFile class.  I makes me comfy to explicitly include the flags that do what I want.  It is easier to discern what is going on in the code when reading it.

MyFileMgr::Open() {

}
0
 
LVL 1

Accepted Solution

by:
GJanusz earned 100 total points
ID: 10683077
Sorry, I discovered that TAB then SPACE posts my comments!

You can do this with fopen(), but I will assume you are using MFC's CFile class.  I makes me comfy to explicitly include the flags that do what I want.  It is easier to discern what is going on in the code when reading it.  I tested most of this code.

MyFileMgr::Open()
{
      CFileException e;
      CFile* pFile;
      pFile = new CFile;
      // Open file for reading and writing; allow others to open for reading only.
      // shareExclusive could be used instead of shareDenyWrite to not allow reading.
      BOOL bResult = pFile->Open(_T("global.txt"),
            CFile::modeReadWrite | CFile::shareDenyWrite, &e);
      if (bResult == FALSE && e.m_cause == CFile::sharingViolation) {
            // sharingViolation is returned if someone else already
            // has the file open.
      }
      else if (bResult == FALSE) {
            // some other error occurred trying to open the file
      }
      else {
            // Success
            // Do Stuff
            pFile->Close();
      }
      delete pFile;
      pFile = NULL;
}

Good Luck!
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10692468
You could use a Mutex to lock other programs using the same resource.

Look at this sample from MSDN (if you are using MFC you may use class CMutex instead)

//------------------------------------------------------------------------------

HANDLE hMutex;

hMutex = CreateMutex
      (
      NULL,                             // no security attributes
      FALSE,                            // initially not owned
      "MutexToProtectDatabase");        // name of mutex

if (hMutex == NULL)
{
                                        // Check for error.
}

When a thread of this process writes to the database, it first requests ownership of the mutex. If it gets ownership, the thread writes to the database and then releases its ownership.

The example uses the try-finally structured exception-handling syntax to ensure that the thread properly releases the mutex object. To prevent the mutex object from being abandoned inadvertently, the finally block of code is executed no matter how the try block terminates — unless the try block includes a call to the TerminateThread function.

BOOL FunctionToWriteToDatabase(HANDLE hMutex)
{
      DWORD dwWaitResult;

 
      dwWaitResult = WaitForSingleObject(
         hMutex,        // handle of mutex
         5000L);        // five-second time-out interval
 
      switch (dwWaitResult)
      {
         case WAIT_OBJECT_0:
            try
            {
                        // Write to the database.
            }

            finally
            {
               if (! ReleaseMutex(hMutex))
               {
                        // Deal with error.
               }

            break;
            }

                        // Cannot get mutex ownership due to time-out.
        case WAIT_TIMEOUT:
            return FALSE;

                        // Got ownership of the abandoned mutex object.
        case WAIT_ABANDONED:
            return FALSE;
      }

      return TRUE;
}

//----------------------------------------------------------------------------------

The mutex is named "MutexToProtectDatabase" and you can get a handle to it by using CreateMutex(...) from threads of different processes.

Regards, Alex



0
 
LVL 1

Author Comment

by:Intern
ID: 10715395
>>GJanusz

In your example (which I think is what I need) I need to put a loop in place to keep trying to open the file.  What is a good command to use that will make the computer wait for a little bit before tyring again?  I have never had to do this and don't really know what to use.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10715497
Try

   Sleep(10);

That will wait 10 milliseconds.

Regards, Alex

0
 
LVL 1

Expert Comment

by:GJanusz
ID: 10725072
You can use Sleep(), as mentioned above -- the argument is the number of milliseconds, but ideally, after a couple seconds or less total of Sleep()ing, you should put up a modeless dialog box with a Cancel button, in case the user gets tired of waiting.  A tight loop with a Sleep is essentially an infinite loop that you are hoping will break free because the resource has gotten freed.  Having said that, the code could be rewritten to the following (not compiled or tested):

MyFileMgr::Open()
{
     CFileException e;
     CFile* pFile;
     pFile = new CFile;

     for (;;) {
          // Open file for reading and writing; allow others to open for reading only.
          // shareExclusive could be used instead of shareDenyWrite to not allow reading.
          BOOL bResult = pFile->Open(_T("global.txt"),
               CFile::modeReadWrite | CFile::shareDenyWrite, &e);
          if (bResult == FALSE && e.m_cause == CFile::sharingViolation) {
               // sharingViolation is returned if someone else already
               // has the file open.
               Sleep(75);
               continue;
          }
          else if (bResult == FALSE) {
               // some other error occurred trying to open the file
          }
          else {
               // Success
               // Do Stuff
               pFile->Close();
          }
          break;
     }
     delete pFile;
     pFile = NULL;
}
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Grammars for C C++ and java 1 138
c++ substatte a varabe for a string in a LPCTSTR statment 8 95
Problem with SqlConnection 4 184
c++, dynamic object by json 1 60
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question