{
    "content": [
        {
            "type": "text",
            "text": "# File::NFSLock (perldoc)\n\n## NAME\n\nFile::NFSLock - perl module to do NFS (or not) locking\n\n## SYNOPSIS\n\nuse File::NFSLock qw(uncache);\nuse Fcntl qw(LOCKEX LOCKNB);\nmy $file = \"somefile\";\n### set up a lock - lasts until object looses scope\nif (my $lock = new File::NFSLock {\nfile      => $file,\nlocktype => LOCKEX|LOCKNB,\nblockingtimeout   => 10,      # 10 sec\nstalelocktimeout => 30 * 60, # 30 min\n}) {\n### OR\n### my $lock = File::NFSLock->new($file,LOCKEX|LOCKNB,10,30*60);\n### do write protected stuff on $file\n### at this point $file is uncached from NFS (most recent)\nopen(FILE, \"+<$file\") || die $!;\n### or open it any way you like\n### my $fh = IO::File->open( $file, 'w' ) || die $!\n### update (uncache across NFS) other files\nuncache(\"someotherfile1\");\nuncache(\"someotherfile2\");\n# open(FILE2,\"someotherfile1\");\n### unlock it\n$lock->unlock();\n### OR\n### undef $lock;\n### OR let $lock go out of scope\n}else{\ndie \"I couldn't lock the file [$File::NFSLock::errstr]\";\n}\n\n## DESCRIPTION\n\nProgram based of concept of hard linking of files being atomic across NFS. This concept was\nmentioned in Mail::Box::Locker (which was originally presented in Mail::Folder::Maildir). Some\nroutine flow is taken from there -- particularly the idea of creating a random local file, hard\nlinking a common file to the local file, and then checking the nlink status. Some ideologies\nwere not complete (uncache mechanism, shared locking) and some coding was even incorrect (wrong\nstat index). File::NFSLock was written to be light, generic, and fast.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **USAGE**\n- **PARAMETERS**\n- **METHODS** (1 subsections)\n- **FAILURE**\n- **LOCKEXTENSION**\n- **REPO**\n- **BUGS**\n- **INSTALL**\n- **AUTHORS**\n- **COPYRIGHT**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "File::NFSLock",
        "section": "",
        "mode": "perldoc",
        "summary": "File::NFSLock - perl module to do NFS (or not) locking",
        "synopsis": "use File::NFSLock qw(uncache);\nuse Fcntl qw(LOCKEX LOCKNB);\nmy $file = \"somefile\";\n### set up a lock - lasts until object looses scope\nif (my $lock = new File::NFSLock {\nfile      => $file,\nlocktype => LOCKEX|LOCKNB,\nblockingtimeout   => 10,      # 10 sec\nstalelocktimeout => 30 * 60, # 30 min\n}) {\n### OR\n### my $lock = File::NFSLock->new($file,LOCKEX|LOCKNB,10,30*60);\n### do write protected stuff on $file\n### at this point $file is uncached from NFS (most recent)\nopen(FILE, \"+<$file\") || die $!;\n### or open it any way you like\n### my $fh = IO::File->open( $file, 'w' ) || die $!\n### update (uncache across NFS) other files\nuncache(\"someotherfile1\");\nuncache(\"someotherfile2\");\n# open(FILE2,\"someotherfile1\");\n### unlock it\n$lock->unlock();\n### OR\n### undef $lock;\n### OR let $lock go out of scope\n}else{\ndie \"I couldn't lock the file [$File::NFSLock::errstr]\";\n}",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 37,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 7,
                "subsections": []
            },
            {
                "name": "USAGE",
                "lines": 22,
                "subsections": []
            },
            {
                "name": "PARAMETERS",
                "lines": 41,
                "subsections": []
            },
            {
                "name": "METHODS",
                "lines": 30,
                "subsections": [
                    {
                        "name": "fork",
                        "lines": 22
                    }
                ]
            },
            {
                "name": "FAILURE",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "LOCKEXTENSION",
                "lines": 4,
                "subsections": []
            },
            {
                "name": "REPO",
                "lines": 4,
                "subsections": []
            },
            {
                "name": "BUGS",
                "lines": 14,
                "subsections": []
            },
            {
                "name": "INSTALL",
                "lines": 12,
                "subsections": []
            },
            {
                "name": "AUTHORS",
                "lines": 13,
                "subsections": []
            },
            {
                "name": "COPYRIGHT",
                "lines": 16,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "File::NFSLock - perl module to do NFS (or not) locking\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use File::NFSLock qw(uncache);\nuse Fcntl qw(LOCKEX LOCKNB);\n\nmy $file = \"somefile\";\n\n### set up a lock - lasts until object looses scope\nif (my $lock = new File::NFSLock {\nfile      => $file,\nlocktype => LOCKEX|LOCKNB,\nblockingtimeout   => 10,      # 10 sec\nstalelocktimeout => 30 * 60, # 30 min\n}) {\n\n### OR\n### my $lock = File::NFSLock->new($file,LOCKEX|LOCKNB,10,30*60);\n\n### do write protected stuff on $file\n### at this point $file is uncached from NFS (most recent)\nopen(FILE, \"+<$file\") || die $!;\n\n### or open it any way you like\n### my $fh = IO::File->open( $file, 'w' ) || die $!\n\n### update (uncache across NFS) other files\nuncache(\"someotherfile1\");\nuncache(\"someotherfile2\");\n# open(FILE2,\"someotherfile1\");\n\n### unlock it\n$lock->unlock();\n### OR\n### undef $lock;\n### OR let $lock go out of scope\n}else{\ndie \"I couldn't lock the file [$File::NFSLock::errstr]\";\n}\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "Program based of concept of hard linking of files being atomic across NFS. This concept was\nmentioned in Mail::Box::Locker (which was originally presented in Mail::Folder::Maildir). Some\nroutine flow is taken from there -- particularly the idea of creating a random local file, hard\nlinking a common file to the local file, and then checking the nlink status. Some ideologies\nwere not complete (uncache mechanism, shared locking) and some coding was even incorrect (wrong\nstat index). File::NFSLock was written to be light, generic, and fast.\n",
                "subsections": []
            },
            "USAGE": {
                "content": "Locking occurs by creating a File::NFSLock object. If the object is created successfully, a lock\nis currently in place and remains in place until the lock object goes out of scope (or calls the\nunlock method).\n\nA lock object is created by calling the new method and passing two to four parameters in the\nfollowing manner:\n\nmy $lock = File::NFSLock->new($file,\n$locktype,\n$blockingtimeout,\n$stalelocktimeout,\n);\n\nAdditionally, parameters may be passed as a hashref:\n\nmy $lock = File::NFSLock->new({\nfile               => $file,\nlocktype          => $locktype,\nblockingtimeout   => $blockingtimeout,\nstalelocktimeout => $stalelocktimeout,\n});\n",
                "subsections": []
            },
            "PARAMETERS": {
                "content": "Parameter 1: file\nFilename of the file upon which it is anticipated that a write will happen to. Locking will\nprovide the most recent version (uncached) of this file upon a successful file lock. It is\nnot necessary for this file to exist.\n\nParameter 2: locktype\nLock type must be one of the following:\n\nBLOCKING\nBL\nEXCLUSIVE (BLOCKING)\nEX\nNONBLOCKING\nNB\nSHARED\nSH\n\nOr else one or more of the following joined with '|':\n\nFcntl::LOCKEX() (BLOCKING)\nFcntl::LOCKNB() (NONBLOCKING)\nFcntl::LOCKSH() (SHARED)\n\nLock type determines whether the lock will be blocking, non blocking, or shared. Blocking\nlocks will wait until other locks are removed before the process continues. Non blocking\nlocks will return undef if another process currently has the lock. Shared will allow other\nprocess to do a shared lock at the same time as long as there is not already an exclusive\nlock obtained.\n\nParameter 3: blockingtimeout (optional)\nTimeout is used in conjunction with a blocking timeout. If specified, File::NFSLock will\nblock up to the number of seconds specified in timeout before returning undef (could not get\na lock).\n\nParameter 4: stalelocktimeout (optional)\nTimeout is used to see if an existing lock file is older than the stale lock timeout. If\ndolock fails to get a lock, the modified time is checked and dolock is attempted again. If\nthe stalelocktimeout is set to low, a recursion load could exist so dolock will only\nrecurse 10 times (this is only a problem if the stalelocktimeout is set too low -- on the\norder of one or two seconds).\n",
                "subsections": []
            },
            "METHODS": {
                "content": "After the $lock object is instantiated with new, as outlined above, some methods may be used for\nadditional functionality.\n\nunlock\n$lock->unlock;\n\nThis method may be used to explicitly release a lock that is acquired. In most cases, it is not\nnecessary to call unlock directly since it will implicitly be called when the object leaves\nwhatever scope it is in.\n\nuncache\n$lock->uncache;\n$lock->uncache(\"otherfile1\");\nuncache(\"otherfile2\");\n\nThis method is used to freshen up the contents of a file across NFS, ignoring what is contained\nin the NFS client cache. It is always called from within the new constructor on the file that\nthe lock is being attempted. uncache may be used as either an object method or as a stand alone\nsubroutine.\n\nfork\nmy $pid = $lock->fork;\nif (!defined $pid) {\n# Fork Failed\n} elsif ($pid) {\n# Parent ...\n} else {\n# Child ...\n}\n",
                "subsections": [
                    {
                        "name": "fork",
                        "content": "ensures the lock is retained within both parent and child processes. WITHOUT this, then when\neither the parent or child process releases the lock, then the entire lock will be lost,\nallowing external processes to re-acquire a lock on the same file, even if the other process\nstill has the lock object in scope. This can cause corruption since both processes might think\nthey have exclusive access to the file.\n\nnewpid\nmy $pid = fork;\nif (!defined $pid) {\n# Fork Failed\n} elsif ($pid) {\n$lock->newpid;\n# Parent ...\n} else {\n$lock->newpid;\n# Child ...\n}\n\nThe newpid() synopsis shown above is equivalent to the one used for the fork() method, but it's\nnot intended to be called directly. It is called internally by the fork() method. To be safe, it\nis recommended to use $lock->fork() from now on.\n"
                    }
                ]
            },
            "FAILURE": {
                "content": "On failure, a global variable, $File::NFSLock::errstr, should be set and should contain the\ncause for the failure to get a lock. Useful primarily for debugging.\n",
                "subsections": []
            },
            "LOCKEXTENSION": {
                "content": "By default File::NFSLock will use a lock file extension of \".NFSLock\". This is in a global\nvariable $File::NFSLock::LOCKEXTENSION that may be changed to suit other purposes (such as\ncompatibility in mail systems).\n",
                "subsections": []
            },
            "REPO": {
                "content": "The source is now on github:\n\ngit clone https://github.com/hookbot/File-NFSLock\n",
                "subsections": []
            },
            "BUGS": {
                "content": "If you spot anything, please submit a pull request on github and/or submit a ticket with RT:\nhttps://rt.cpan.org/Dist/Display.html?Queue=File-NFSLock\n\nFIFO\nLocks are not necessarily obtained on a first come first serve basis. Not only does this not\nseem fair to new processes trying to obtain a lock, but it may cause a process starvation\ncondition on heavily locked files.\n\nDIRECTORIES\nLocks cannot be obtained on directory nodes, nor can a directory node be uncached with the\nuncache routine because hard links do not work with directory nodes. Some other algorithm might\nbe used to uncache a directory, but I am unaware of the best way to do it. The biggest use I can\nsee would be to avoid NFS cache of directory modified and last accessed timestamps.\n",
                "subsections": []
            },
            "INSTALL": {
                "content": "Download and extract tarball before running these commands in its base directory:\n\nperl Makefile.PL\nmake\nmake test\nmake install\n\nFor RPM installation, download tarball before running these commands in your topdir:\n\nrpm -ta SOURCES/File-NFSLock-*.tar.gz\nrpm -ih RPMS/noarch/perl-File-NFSLock-*.rpm\n",
                "subsections": []
            },
            "AUTHORS": {
                "content": "Paul T Seamons (paul@seamons.com) - Performed majority of the programming with copious amounts\nof input from Rob Brown.\n\nRob B Brown (bbb@cpan.org) - In addition to helping in the programming, Rob Brown provided most\nof the core testing to make sure implementation worked properly. He is now the current\nmaintainer.\n\nAlso Mark Overmeer (mark@overmeer.net) - Author of Mail::Box::Locker, from which some key\nconcepts for File::NFSLock were taken.\n\nAlso Kevin Johnson (kjj@pobox.com) - Author of Mail::Folder::Maildir, from which Mark Overmeer\nbased Mail::Box::Locker.\n",
                "subsections": []
            },
            "COPYRIGHT": {
                "content": "Copyright (C) 2001\nPaul T Seamons\npaul@seamons.com\nhttp://seamons.com/\n\nCopyright (C) 2002-2018,\nRob B Brown\nbbb@cpan.org\n\nThis package may be distributed under the terms of either the\nGNU General Public License\nor the\nPerl Artistic License\n\nAll rights reserved.\n",
                "subsections": []
            }
        }
    }
}