Page 1 of 2
Unlock() invalid lock object
Posted: Sat Feb 06, 2016 8:57 pm
by BSzili
Anchor, the author of the Google Drive handler recently got OS4 FE Classic up and running, and started porting the handler to OS4. He already made an account here, but he is still waiting for it to be activated, so I'm forwarding his question. Like those who tried the 68k version, he is stuck with the following error:
http://fourflash.com/misc/os4.png
He asks when is a lock considered invalid?
Re: Unlock() invalid lock object
Posted: Sat Feb 06, 2016 10:47 pm
by broadblues
When you do something like:
Code: Select all
#include <proto/dos.h>
int main(int argc, char *argv[])
{
BPTR foo;
if(foo = IDOS->Lock("T:",SHARED_LOCK))
{
IDOS->Printf("%08lx\n",foo);
IDOS->UnLock(foo);
IDOS->UnLock(foo);
}
}
ie a lock that been unlocked already.
It's agood idea to always set the BPTR to 0L after UnLock() and to test for )LO before Unlocking to avoid accidental double UnLocking etc.
Re: Unlock() invalid lock object
Posted: Mon Feb 08, 2016 1:23 am
by colinw
Just incase you were wondering about specifics...
The warning is triggered when the struct Lock supplied to IDOS->UnLock() has fl_Port==NULL.
The filesystems never access their own locks fl_Port member when they unlock them,
however DOS does, it needs it to identify the handler obviously, so IDOS->UnLock() sets
fl_Port to NULL to invalidate it, this protects from the UnLock() twice problem and also
provides a stack trace if you have the kernel debuglevel >0 when someone tries to do it again.
This has been in force since DOS 52.39 (26-05-2008)
Re: Unlock() invalid lock object
Posted: Mon Feb 08, 2016 11:47 pm
by xenic
colinw wrote:Just incase you were wondering about specifics...
The warning is triggered when the struct Lock supplied to IDOS->UnLock() has fl_Port==NULL.
The filesystems never access their own locks fl_Port member when they unlock them,
however DOS does, it needs it to identify the handler obviously, so IDOS->UnLock() sets
fl_Port to NULL to invalidate it, this protects from the UnLock() twice problem and also
provides a stack trace if you have the kernel debuglevel >0 when someone tries to do it again.
This has been in force since DOS 52.39 (26-05-2008)
The warning in question is being posted during the execution of the
list command. I doubt if the list command is unlocking anything twice or we would get the warning for other devices too. It would seem that the problem originates in the
Google Drive handler code. That brings up a couple of other questions:
1. Does a filesystem handler create, alter or manipulte locks or are locks read-only for handlers?
2. If handlers are allowed to create, alter or manipulate locks, how can they do so if the lock structure is not defined (declared) anywhere in the current SDK?
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 12:38 am
by chris
xenic wrote:The warning in question is being posted during the execution of the list command. I doubt if the list command is unlocking anything twice or we would get the warning for other devices too. It would seem that the problem originates in the Google Drive handler code. That brings up a couple of other questions:
1. Does a filesystem handler create, alter or manipulte locks or are locks read-only for handlers?
Yes.
2. If handlers are allowed to create, alter or manipulate locks, how can they do so if the lock structure is not defined (declared) anywhere in the current SDK?
Look for "struct Lock".
Handlers are wholly responsible for the creation and deletion of locks, dos.library only passes the pointers backwards and forwards from ACTION_LOCATE_OBJECT and ACTION_FREE_LOCK (ok, it probably does other stuff too, but the handler will allocate and free the memory, and fill in the contents)
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 3:53 am
by tonyw
Handlers are wholly responsible for the creation and deletion of locks
There is more to it for modern file systems. DOS creates the Lock (AllocDOSObject() call) and deletes it when the Lock is released (FreeDOSObject() call).
The file system appends its own internal data to the DOS Lock, so that you end up with something like this:
Code: Select all
struct FSLock
{
struct Lock;
// now our own stuff
struct FSObject FSObject;
uint64 DiskAddress;
uint64 CurrentFilePosition;
(etc)
};
The file system requests the Lock from DOS when a call takes out a Lock on an Object. You give DOS the overall size that you require in the AllocDOSObject() call and DOS returns the structure which is then used by all entities.
As Colin said earlier, only DOS may null out the fl_Port when the Lock is released by the file system (as the result of the UnLock() call).
Within limits, the file system does not know or care what DOS keeps in its Lock structure. There are some fields that the handler must fill in, but most of it is DOS private stuff, just as the handler's private stuff is unknown to DOS.
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 9:22 am
by salass00
So is it UnLock(lock) or FreeDosObject(DOS_LOCK, lock) that sets fl_Port to NULL?
If it's the former it will cause problems for file systems that use the same lock structure for more than one "lock" on the same file system object.
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 12:48 pm
by tonyw
UnLock(lock) calls IDOS->FreeDOSObject(lock). In freeing the Lock structure, DOS nulls out the fl_Port field just in case.
Since the DOS Lock structure is allocated from the DOS internal pool, it can still be accessed (without crashing the machine) even after release, although it may be by then a completely different structure..
Reusing an existing Lock structure for another instance sounds rather dangerous to me. Why not call DupLock() and use the new Lock?
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 1:48 pm
by salass00
UnLock(lock) calls IDOS->FreeDOSObject(lock). In freeing the Lock structure, DOS nulls out the fl_Port field just in case.
It's the file system that calls FreeDosObject() to free locks.
Reusing an existing Lock structure for another instance sounds rather dangerous to me. Why not call DupLock() and use the new Lock?
Not really. For shared locks you just keep a reference count and free the lock only when this reaches zero and for file handles you use a separate structure to store the current file position in and other such state data (pointer to which you store in fh_Arg1).
It probably won't work too well if the locks are relinquished to the dos.library lock handler but for legacy file systems which don't support the ACTION_SHUTDOWN packet this isn't a problem.
Re: Unlock() invalid lock object
Posted: Tue Feb 09, 2016 4:48 pm
by xenic
chris wrote:
Look for "struct Lock".
Handlers are wholly responsible for the creation and deletion of locks, dos.library only passes the pointers backwards and forwards from ACTION_LOCATE_OBJECT and ACTION_FREE_LOCK (ok, it probably does other stuff too, but the handler will allocate and free the memory, and fill in the contents)
Sorry, I was looking for "struct FileLock" which has apparently been replaced for OS4.
If the fl_Port is being nulled out by DOS when the filesystem calls IDOS->FreeDOSObject(lock), then it sounds like "Google Drive handler" might be freeing the lock prematurely.