How to avoid multi-process overlap in a log file - without locking?

Hi all.

 

I have a function which saves text data to a log file.  I want process A to write a bunch of data (an XML transaction) and THEN have process B write some other data. Currently the function opens the log file with extend, writes the data, and closes the file.  (The write uses "WITH NO CONTROL").  Most of the time things are fine, but the red hat enterprise server it's running on will occasionally merge the output together - character by character so it looks encrypted!    I know I can fix this by simply adding an extra step - try to lock the file and keep trying until it becomes available.  I'm wondering if there some kind of setting that will 'chunk' the data together so the two processes do not overlap each other.   Note: I'm fairly sure I already tried "BLOCK CONTAINS" a while back, with a size large enough for the chunk of data - didn't help.  Runtime is version 9.2.1

  • I think file locking is your best bet. You need something to make access to the file mutually exclusive and locking support is built in. Surprisingly, with most popular file systems, the data from two simultaneous write() system calls of blocks of data in different processes may be interleaved. If you can't do it from the OS level you aren't going to be able to do it from the COBOL level without a mutex of some sort. There may be a way to wait for the file lock without doing a busy loop, but I'm not thinking of it right now. Maybe someone else has done that.
  • Verified Answer

    I remembered what my idea for the non-busy wait for the file lock. Use a record lock on another file along with WAIT_FOR_LOCKS 1 or 2. This should have the OS do the waiting for the lock so you don't have to. You'd be leveraging this functionality to control access to the log file instead of locking the log file itself and then polling to see when the file lock is available. I haven't done this, but I think the functionality is there.
  • Verified Answer

    I remembered what my idea for the non-busy wait for the file lock. Use a record lock on another file along with WAIT_FOR_LOCKS 1 or 2. This should have the OS do the waiting for the lock so you don't have to. You'd be leveraging this functionality to control access to the log file instead of locking the log file itself and then polling to see when the file lock is available. I haven't done this, but I think the functionality is there.
  • Verified Answer

    I remembered what my idea for the non-busy wait for the file lock. Use a record lock on another file along with WAIT_FOR_LOCKS 1 or 2. This should have the OS do the waiting for the lock so you don't have to. You'd be leveraging this functionality to control access to the log file instead of locking the log file itself and then polling to see when the file lock is available. I haven't done this, but I think the functionality is there.
  • Thanks for the suggestions. I won't be able to use the WAIT_FOR_LOCKS environment variable since I have other threads which might get affected, but this solidifies my plans - Since I have to use locking and a loop anyway, I'm going to use a separate lock file, build my own loop to wait for the record to be locked, (sleeping for .01 if it IS locked before trying again) once I have the lock, then I open/write/close the log file, then release the lock. That helped!