mWriteFile(nil),
mWriteFilename(mReadFilename + ",") // XXX Do some more work here like resolving symlinks/aliases etc.
{
+ debug("atomicfile", "%p construct name=%s", this, mReadFilename.c_str());
// We only support databases with string names of non-zero length.
if (inDbName.dbLocation() != nil || inDbName.dbName().length() == 0)
CssmError::throwMe(CSSMERR_DL_INVALID_DB_LOCATION);
AtomicFile::~AtomicFile()
{
// Assume there are no more running theads in this object.
+ debug("atomicfile", "%p destroyed", this);
// Try hard to clean up as much as possible.
try
void
AtomicFile::close()
{
+ debug("atomicfile", "%p close", this);
StLock<Mutex> _(mReadLock);
// If we have no read file we have nothing to close.
AtomicFile::VersionId
AtomicFile::commit()
{
+ debug("atomicfile", "%p commit", this);
StLock<Mutex> _(mReadLock);
if (mWriteFile == nil)
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
// Close all unused files (in particular aOpenFile) and remove them from mOpenFileMap
endWrite();
+ debug("atomicfile", "%p commit done", this);
return aVersionId;
}
catch (...)
unlink(mWriteFilename);
}catch(...) {}
endWrite();
+ debug("atomicfile", "%p commit failed, rethrowing", this);
throw;
}
}
void
AtomicFile::rollback()
{
+ debug("atomicfile", "%p rollback", this);
StLock<Mutex> _(mReadLock);
if (mWriteFile == nil)
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
if (mCreating)
unlink(mReadFilename);
endWrite();
+ debug("atomicfile", "%p rollback complete", this);
}
catch(...)
{
unlink(mWriteFilename);
}catch(...) {}
endWrite();
+ debug("atomicfile", "%p rollback failed, rethrowing", this);
throw;
}
}
flags = O_RDONLY;
mState = Read;
}
+ debug("atomicfile", "%p openfile(%s,%s%s,%d,0x%x) -> flags=0x%x, state=%d",
+ this, inFilename.c_str(), write ? "write" : "read", lock ? ",lock" : "",
+ inVersionId, mode, flags, mState);
mFileRef = ::open(inFilename.c_str(), flags, mode);
if (mFileRef == -1)
{
int error = errno;
+ debug("atomicfile", "%p openfile open failed(errno=%d)", this, error);
#if _USE_IO == _USE_IO_POSIX
// Do the obvious error code translations here.
// Now try the open again.
mFileRef = ::open(inFilename.c_str(), flags, mode);
+ debug("atomicfile", "%p openfile reopen %s (%d)",
+ this, (mFileRef == -1) ? "failed" : "ok", errno);
error = mFileRef == -1 ? errno : 0;
if (error == ENOENT)
CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);
void
AtomicFile::OpenFile::close()
{
+ IFDEBUG(if (mState != Closed) debug("atomicfile", "%p openfile closing(ref=%d)",
+ this, mFileRef));
int error = 0;
if (mAddress != NULL)
{
#if _USE_IO == _USE_IO_POSIX
+ debug("atomicfile", "%p openfile is unmapping %p:%ld", this, mAddress, mLength);
if (::munmap(const_cast<uint8 *>(mAddress), mLength) == -1)
error = errno;
#else
+ debug("atomicfile", "%p openfile deleting %p", this, mAddress);
delete[] mAddress;
#endif