public boolean pinned(final String db) {
return datas.pinned(db) || TableDiskAccess.locked(db, this);
}
Leads to Datas.java.... and TableDiskAccess.java
Datas.java simply records in memory which dbs are 'pinned' and how often.
TableDiskAccess.java does physical file locking.
Looking for calls to 'unpin' ... finds one in Close.java:
/**
* Evaluates the 'close' command and closes the current database.
*
So it appears that BaseX expects database accesses to be wrapped in a OPEN...CLOSE brace. We don't issue neither OPEN nor CLOSE... so I'm guessing it's done internally as part of XQUERY?
Suppose one client run an XQUERY against a db, which involves (internally) one or more 'OPEN' calls, then accesses, then 'CLOSE' commands --- how do you synchronize this client with others? Do you have a master lock so that the server processes only one query/command at a time?
If so, that would be bad for performance... if not, your assumption that you can throw an error in CreateDB.run if the db is pinned is wrong. Instead, you'll need a 'wait_until_unpinned' method that CreateDB calls until the db it's trying to create is no longer pinned. It would need to wait on a signaling device that's signaled in unpin(). (Note that we are recreating a database with the same name over and over, even while some clients perform XQUERY on the then-current version of that database.) This mode of failure would, in essence, be a race condition that would manifest itself if there happened to be a read access to the db by one client while another is trying to create a db with the same name.
I actually don't think that's the failure we're seeing, based on the fact that restarting the server allows the operation to succeed. The latter would point to not calling 'close()' on some path in a previous db operation, leading to a stale entry in the datas. list.
- Godmar