[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::axp-developer

Title:Alpha Developer Support
Notice:[email protected], 800-332-4786
Moderator:HYDRA::SYSTEM
Created:Mon Jun 06 1994
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3722
Total number of notes:11359

3680.0. "Dharma Systems" by HYDRA::AXPDEVELOPER (Alpha Developer support) Thu May 29 1997 17:48

    Company Name :  Dharma Systems
    Contact Name :  Dave Partridge
    Phone        :  603-886-1400 x12
    Fax          :  
    Email        :  [email protected]
    Date/Time in :  29-MAY-1997 16:46:49
    Entered by   :  Geritt Saylor
    SPE center   :  MRO

    Category     :  VMS
    OS Version   :  
    System H/W   :  


    Brief Description of Problem:
    -----------------------------
He's opening a file with fopen() for use by two processes.  He
gets a file lock error when he tries to write to the file due
to concurrent access.  Needs solution.

Gerrit
T.RTitleUserPersonal
Name
DateLines
3680.1HYDRA::AXPDEVELOPERAlpha Developer supportThu May 29 1997 18:1823
Date:	29-MAY-1997 17:17:28.67
From:	HYDRA::AXPDEVELOPER "[email protected]"
Subj:	fopen/VMS problems
To:	[email protected]
CC:	AXPDEVELOPER
15 records
Attributes: New message

Dave:

There's a workaround to this problem via a DECC extension.  You'll
find the details in the online documentation under the DECC Runtime
library and file creation.  Basically you'll want a "CTX=SHR" argument
to fopen. 

If you have any questions, feel free to call.  Our VMS person here has left
for the afternoon, so you'll have a quicker response tomorrow if you call
then.

Please reference your call by my name or call number 1997-3680.

Gerrit Saylor
Alpha Developer Support
3680.2HYDRA::AXPDEVELOPERAlpha Developer supportWed Jun 04 1997 16:525
Dave called again and is having some problems in synchronizing
two processes writing to a file and seeing the same file
length.  He's going to send some more example code.

Gerrit
3680.3HYDRA::AXPDEVELOPERAlpha Developer supportWed Jun 04 1997 18:2927
From: "[email protected]"
<[email protected]>
Reply-To: "[email protected]" <[email protected]>
To: alpha-developer <[email protected]>
Subject: Attn: Gerrit Saylor (1997-3680)
Date: Wed, 4 Jun 1997 16:14:24 -0400
X-Mailer:  Microsoft Exchange Server Internet Mail Connector Version 4.0.996.15
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Hello Gerrit,

Having run some more tests to determine the behaviour, I think I have found that
it is the same as on unix, that is, if two processes have the file open and
one extends it, then if the one that closes it last will be the one that sets
the file length.  Thus, if the one that extended the file closes it last,
the file will be extended, if it closes it first, the extension will be lost.
This was causing a problem for me because the file locking mechanism has
not yet been converted to a VMS format and so file access was not being
blocked.

Thank you for your time.

Regards
Dave Partridge
[email protected]
3680.4HYDRA::AXPDEVELOPERAlpha Developer supportThu Jun 05 1997 16:54215
From: "[email protected]" 
<[email protected]>
Reply-To: "[email protected]" <[email protected]>
To: alpha-developer <[email protected]>
Subject: ATTN: Gerrit  (spoke too soon re 1997-3680)
Date: Wed, 4 Jun 1997 16:54:50 -0400
X-Mailer:  Microsoft Exchange Server Internet Mail Connector Version 4.0.996.15
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Content-Lines: 56

Hello Gerrit,

I spoke a bit too soon.  Further experimentation shows that it is not behaving
like Unix.  My test program does not lose the data on Unix.  I do get the
behaviour I want if I open the file with O_RDONLY instead of O_RDWR, but
unfortunately, I cannot tell in my execution path how the file is going to
be used when I open it.  The behaviour I see is as follows:

Process 1 creates a file and write 10 bytes to it, then closes and reopens it.
Process 2 opens the file and reads from it, seeing the 10 bytes.
Process 1 writes another 10 bytes to the file.

If Process 1 closes the file, then Process 2, then subsequent reads will
	only see 10 bytes.

If Process 2 closes the file, then Process 1, then subsequent reads will
	see 20 bytes.

If Process 2 opens the file with O_RDONLY, then it apparently does not update
the file header on close and subsequent reads will see all 20 bytes, regardless
of which process closes the file first.

To see this behaviour, compile and link the three c++ files included
below.  

To see the data vanish:

Run dh_write, do not press return to do the second write
Run dh_read, do not press return to close the file
Press return on dh_write to do the second write
Press return on dh_write to close the file
Press return on dh_read to close the file
re-run dh_read, only 10 bytes will be read

To have the data remain

Run dh_write, do not press return to do the second write
Run dh_read, do not press return to close the file
Press return on dh_write to do the second write
Press return on dh_read to close the file
Press return on dh_write to close the file
re-run dh_read, 20 bytes will be read

Repeat the first sequence using dh_read1 to see that the data remains
when the file is opened with O_RDONLY.

Is there anything I can do to prevent the file header being written back
out when the file has been opened with O_RDWR, but the process has not
updated the file?

Thank you for your help.

Dave Partridge
[email protected]


----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: dh_write.cxx
X-Sun-Content-Lines: 44

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
	int creat_fd, fd, status;
	char buff[10];
	
	fd = open("dh_test.tst", O_RDWR | O_TRUNC | O_CREAT, 0, 
"shr=put","shr=upd","shr=del","shr=get");
	if (fd < 0)
		perror ("First open failed\n");
   	status = lseek(fd,  0, SEEK_SET);
	if (status < 0)
		perror ("lseek to 0 failed\n");
	memset(buff,'a',10);
	status = write(fd, buff, 10);	
	if (status != 10)
	{	perror("write of 10 bytes to 0 returned ");
		printf("%d",status);
	}
	close(fd);

	printf("Press return to do second write\n");
	gets(buff);
	fd = open("dh_test.tst", O_RDWR | O_CREAT, 0, 
"shr=put","shr=upd","shr=del","shr=get");
	if (fd < 0)
		perror ("Second open  failed\n");
	status = lseek(fd,  10, SEEK_SET);
	if (status < 0)
		perror ("lseek to 10 failed\n");
	memset(buff,'b',10);
	status = write(fd, buff, 10);	
	if (status != 10)
	{	perror("write of 10 bytes to 10 returned ");
		printf("%d",status);
	}
	printf("Press return to close file\n");
	gets(buff);
	close(fd);

	return 0;
}           
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: dh_read.cxx
X-Sun-Content-Lines: 38

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
	int creat_fd, fd, status;
	char buff[20];
	
	fd = open("dh_test.tst", O_RDONLY, 0, 
"shr=put","shr=upd","shr=del","shr=get");
	if (fd < 0)
		perror ("open failed\n");

	status = lseek(fd,  0, SEEK_SET);
	if (status < 0)
		perror ("lseek to 0 failed\n");
	status = read (fd, buff, 20);
	if (status < 0)
		perror ("read from 0 failed\n");
	else
		printf("Read from 0 got %d bytes\n",status);

	status = lseek(fd,  10, SEEK_SET);
	if (status < 0)
		perror ("lseek to 10 failed\n");
	status = read (fd, buff, 10);
	if (status < 0)
		perror ("read from 10 failed\n");
	else
		printf("Read from 10 got %d bytes\n",status);

	printf("Press return to close file\n");
	gets(buff);
	close(fd);

	return 0;
}           
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: dh_read1.cxx
X-Sun-Content-Lines: 38

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
	int creat_fd, fd, status;
	char buff[20];
	
	fd = open("dh_test.tst", O_RDWR, 0, 
"shr=put","shr=upd","shr=del","shr=get");
	if (fd < 0)
		perror ("open failed\n");

	status = lseek(fd,  0, SEEK_SET);
	if (status < 0)
		perror ("lseek to 0 failed\n");
	status = read (fd, buff, 20);
	if (status < 0)
		perror ("read from 0 failed\n");
	else
		printf("Read from 0 got %d bytes\n",status);

	status = lseek(fd,  10, SEEK_SET);
	if (status < 0)
		perror ("lseek to 10 failed\n");
	status = read (fd, buff, 10);
	if (status < 0)
		perror ("read from 10 failed\n");
	else
		printf("Read from 10 got %d bytes\n",status);

	printf("Press return to close file\n");
	gets(buff);
	close(fd);

	return 0;
}           
3680.5HYDRA::AXPDEVELOPERAlpha Developer supportThu Jun 05 1997 18:0232
From:	HYDRA::AXPDEVELOPER "[email protected]"  5-JUN-1997 17:01:29.99
To:	SMTP%"[email protected]"
CC:	SAYLOR,AXPDEVELOPER
Subj:	RE: 1997-3680

Dave,

I guess I'm not seeing the same results that you shared with Gerritt.
Is this what you expected, or not?
---process 1---
$ run dhwrite
Press return to do second write

Press return to close file

$
---process 2---
$ run dhread
Read from 0 got 20 bytes
Read from 10 got 10 bytes
Press return to close file

$

I did modify the fopen statement on dh_write and added "ctx=rec".  Please
review the various options in the C Run-Time Manual.  As a rule on VMS, the 
first process to open/create a file determines the access attributes for other
processes that open the same file.

I'll be out of the office tomorrow.  Pick it up again on Monday.

Mark Schafer