HOME  NEWS  FORUM  DOWNLOAD  LINK
OpenCOBOL - an open-source COBOL compiler
Main Menu
Download
Documentation
Development
Who's Online
14 user(s) are online (4 user(s) are browsing Forum)

Members: 0
Guests: 14

more...
Powered by
SourceForge

Xoops

Creative Commons

OpenCOBOL Forum Index
   OpenCOBOL
     Ramblings on FILE SHARING
Register To Post

Threaded | Newest First Previous Topic | Next Topic | Bottom
Poster Thread
JoeRobbins
Posted on: 2012/10/2 12:52
Not too shy to talk
Joined: 2011/8/30
From: Nottinghamshire
Posts: 21
Ramblings on FILE SHARING
While rewriting the fileio.c "module" of OpenCOBOL, I am having problems understanding the design intention and/or code implementation of (whole) file locking or sharing. (EMPHASISE: none of this relates to RECORD LOCKING.) Here are my notes - all corrections & comments welcomed!.

1. Relevant COBOL statements:
	SELECT ...
	[ SHARING WITH ALL OTHER ]
	[ SHARING WITH NO OTHER ]
	[ SHARING READ ONLY ]
                           
	OPEN ... 
	[ SHARING WITH ALL OTHER ]
	[ SHARING WITH NO OTHER ]
	[ SHARING READ ONLY ]


Alternate:
	SELECT ...
	[ LOCK MODE IS EXCLUSIVE ]
	
	OPEN ... WITH LOCK


2. OpenCOBOL P-Guide documents FILE SHARING in:


Section 6.1.9 Controlling Concurrent Access to Files
Sharing Effect
Option
ALL     When your program opens a file in this manner, no restrictions will be placed on other programs
OTHER   attempting to OPEN the file after your program did. This is the default sharing mode.

NO      When your program opens a file in this manner, your program announces that it is unwilling to allow
OTHER   any other program to have any access to the file as long as you are using that file; OPEN attempts
        made in other programs will fail with a file status of 37 (“PERMISSION DENIED”) until such time as you
        CLOSE the file (see section 6.9).

READ    Opening a file in this manner indicates you are willing to allow other programs to OPEN the file for
ONLY    INPUT while you have it OPEN. If they attempt any other OPEN, their OPEN will fail with a file status
        of 37.


Section 6.31: OPEN

The WITH NO REWIND and WITH LOCK clauses are non-functional.



3. OpenCOBOL Compiler

3.1 Compiler generates:
		001180     open output sharing with all other file1.

		test34.CBL:118: Warning: 'SHARING ALL OTHER' not implemented


This is strange! According to the manual: "This is the default sharing mode" (cf. 2 above).



3.2 cobc/parser.y

sharing_clause:
  SHARING _with sharing_option  { current_file->sharing = $3; }
;

sharing_option:
  ALL _other                    { $$ = NULL; PENDING ("SHARING ALL OTHER"); }
| NO _other                     { $$ = cb_int1; }
| READ ONLY                     { $$ = cb_int0; }
;


This implies f->sharing is a binary: 0..SHARE_WITH_OTHER_READERS 1..EXCLUSIVE
(3rd state NULL - the initialised default value - indicates NYI and is presumably converted to one of the other 2 values).


3.3 cobc/typeck.c
	void cb_emit_open (cb_tree file, cb_tree mode, cb_tree sharing) 
    ...
        if (sharing == NULL) {
                sharing = CB_FILE (file)->sharing ? CB_FILE (file)->sharing : cb_int0;
        }

        /* READ ONLY */
        if (sharing == cb_int0 && CB_INTEGER (mode)->val != COB_OPEN_INPUT) {
                sharing = cb_int1;
        }

        cb_emit (cb_build_funcall_4 ("cob_open", file, mode,
                 sharing, CB_FILE(file)->file_status));


I interpret this as: if this OPEN statement didn't use SHARING or used SHARING ALL then use the SHARING value from the SELECT. If the SELECT statement didn't use SHARING or used SHARING ALL then use SHARE_WITH_OTHER_READERS.

If SHARE_WITH_OTHER_READERS and the OPEN mode is not INPUT convert to EXCLUSIVE.


Now this is a worry: ONLY files opened INPUT can be shared?


4. OpenCOBOL run-time - fileio.c

4.1 RELATIVE & SEQUENTIAL Files.
static int cob_file_open (cob_file *f, char *filename, const int mode, const int sharing)
...

#ifdef HAVE_FCNTL
	/* lock the file */
	if (memcmp (filename, "/dev/", 5)) {
		memset ((unsigned char *)&lock, 0, sizeof (struct flock));
		lock.l_type = (sharing || mode == COB_OPEN_OUTPUT) ? F_WRLCK : F_RDLCK;
		lock.l_whence = SEEK_SET;
		lock.l_start = 0;
		lock.l_len = 0;
		if (fcntl (fileno (fp), F_SETLK, &lock) < 0) {
			ret = errno;
			fclose (fp);
			return ret;
		}
	}
#endif


I interpret this as: if sharing is EXCLUSIVE or OPEN mode is OUTPUT then take a write-lock otherwise take a read-lock. Please note

Problem 1:
The man page for (Linux) fcntl states:
"In order to place a read lock, fd must be open for reading. In order to place a write lock, fd must be open for writing. To place both types of lock, open a file read-write."

So my guess is that: OPEN INPUT SHARING WITH NO OTHER will fail because fileio will attempt to take a write-lock on a file opened input. Sure enough, on test: this OPEN throws file-status = 30 (PERMANENT ERROR).



Problem 2:

The macros for COB_OPEN (see fileio.h) are NOT combinable "bit flags", they are distinct integer values.
#define COB_OPEN_CLOSED 0
#define COB_OPEN_INPUT  1
#define COB_OPEN_OUTPUT 2
#define COB_OPEN_I_O    3
#define COB_OPEN_EXTEND 4



The expression: "mode == COB_OPEN_OUTPUT" is not the same as "mode != COB_OPEN_INPUT".
So we see cobc/typeck.c (cf. 3.3) decides that if a file is not opened input then it must be locked EXCLUSIVE. Whereas fileio.c implies that if a file is opened output then it must be locked EXCLUSIVE. Quoting MF COBOL/2 manual: "A file opened for OUTPUT is implicitly defined as a file with an exclusive lock, that is, it is not shareable." And ... "Only shareable files opened for I-O can acquire record locks.". So looks like fileio.c is correct - and cobc wrong.


4.2 INDEXED FILES
static int indexed_open (cob_file *f, char *filename, const int mode, const int sharing)
...
	if (!f->lock_mode) {
		if (mode != COB_OPEN_INPUT) {
			lmode = ISEXCLLOCK;
		} else {
			lmode = ISMANULOCK;
		}
	} else if ((f->lock_mode & COB_LOCK_EXCLUSIVE)) {
		lmode = ISEXCLLOCK;
	} else if ((f->lock_mode & COB_LOCK_AUTOMATIC) && mode != COB_OPEN_INPUT) {
		lmode = ISAUTOLOCK;
	} else {
		lmode = ISMANULOCK;
	}


The sharing arg is NOT referenced at all in this function. This is surprising: ISAM files ignore SHARING entirely and interpret only the LOCK_MODE, determined in the SELECT statement. This explains why INDEXED files are not subject to the anomolies/restrictions described earlier.



5. EMPIRICAL RESULTS

Program A opens a SEQUENTIAL file using INPUT OUTPUT or IO and a SHARING option. Program B attempts to open the same file, iterating through INPUT OUTPUT or IO and each SHARING option. The file-status is noted. Program A moves to the next OPEN and program B repeats the entire cycle. This continues until Program A and B have attempted every combination of OPEN / SHARING.

In most cases we expect to get COB_STATUS_61_FILE_SHARING. For clarity, these are omitted in the results below. (Note: file-status 61 is returned, not 37 (“PERMISSION DENIED”) as stated in OpenCOBOL P-Guide.) Disputed results are annotated "?".

                             Program: A
                   SHARING:  WITH ALL OTHER    READ ONLY         WITH NO OTHER
                 OPEN MODE:  OUTPUT INPUT I-O  OUTPUT INPUT I-O  OUTPUT INPUT I-O
 
Program: B
SHARING                
DEFAULT          OUTPUT                                                 --      
DEFAULT          INPUT              00                00                --      
DEFAULT          I-O                61?                                 --      
WITH ALL OTHER   OUTPUT                                                 --      
WITH ALL OTHER   INPUT              00    61?         00    61?         --      
WITH ALL OTHER   I-O                61?   61?                           --      
READ ONLY        OUTPUT                                                 --      
READ ONLY        INPUT              00                00                --      
READ ONLY        I-O                61?                                 --      
WITH NO OTHER    OUTPUT                                                 --      
WITH NO OTHER    INPUT       30?    30?  30?   30?    30?   30?  30?    --    30?
WITH NO OTHER    I-O                                                    --      




6. CONCLUSION

File level locking could be implemented at COBOL file level instead of relying on underlying interfaces that vary with file type (ORGANIZATION). This would provide a uniform, consistent solution. Any feature impossible to implement on a target platform could generate a warning and continue in a degraded mode.
Would it be OK for a re-implementation to "work" only within the COBOL domain?
btiffin
Posted on: 2012/10/4 4:02
Webmaster
Joined: 2008/6/7
From: CANADA
Posts: 1196
Re: Ramblings on FILE SHARING
Big post Joe.

It might take awhile to develop responses, but in the meanwhile, thanks for the notes, there are some things to look through.

Cheers,
Brian
Threaded | Newest First Previous Topic | Next Topic | Top

Register To Post
 
Copyright (C) 2005 The OpenCOBOL Project. All rights reserved.
Powered by Xoops2 | PHP | MySQL | Apache
ocean-net