Consolidated common UserlandFS and RamFS headers and support classes a bit.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20174 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-02-20 01:25:04 +00:00
parent d4d9831990
commit 92864b3702
17 changed files with 32 additions and 1486 deletions

View File

@ -47,17 +47,17 @@ public:
template<typename Element>
class DLListLinkImpl {
private:
typedef DLListLink<Element> Link;
typedef DLListLink<Element> MyLink;
public:
DLListLinkImpl() : fDLListLink() {}
~DLListLinkImpl() {}
Link *GetDLListLink() { return &fDLListLink; }
const Link *GetDLListLink() const { return &fDLListLink; }
MyLink *GetDLListLink() { return &fDLListLink; }
const MyLink *GetDLListLink() const { return &fDLListLink; }
private:
Link fDLListLink;
MyLink fDLListLink;
};
// DLListStandardGetLink

View File

@ -115,6 +115,7 @@ void dbg_printf_end();
#define FUNCTION(x) TFUNCTION(x)
#define FUNCTION_START() TFUNCTION_START()
#define FUNCTION_END() TFUNCTION_END()
#define DARG(x) x
#define D(x) {x;};
#else
#define PRINT(x) ;
@ -128,6 +129,7 @@ void dbg_printf_end();
#define FUNCTION(x) ;
#define FUNCTION_START() ;
#define FUNCTION_END() ;
#define DARG(x)
#define D(x) ;
#endif

View File

@ -12,7 +12,7 @@
#define ENABLE_BA_PANIC 1
#if ENABLE_BA_PANIC
#define BA_PANIC(x) { DEBUGGER(x); BlockAllocator::fPanic = true; }
#define BA_PANIC(x) { PANIC(x); BlockAllocator::fPanic = true; }
#endif
class AllocationInfo;

View File

@ -1,266 +0,0 @@
// DLList.h
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of a copyright holder shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization of the
// copyright holder.
#ifndef DL_LIST_H
#define DL_LIST_H
// DLListLink
template<typename Element>
class DLListLink {
public:
DLListLink() : previous(NULL), next(NULL) {}
~DLListLink() {}
Element *previous;
Element *next;
};
// DLListLinkImpl
template<typename Element>
class DLListLinkImpl {
private:
typedef DLListLink<Element> MyLink;
public:
DLListLinkImpl() : fDLListLink() {}
~DLListLinkImpl() {}
MyLink *GetDLListLink() { return &fDLListLink; }
const MyLink *GetDLListLink() const { return &fDLListLink; }
private:
MyLink fDLListLink;
};
// DLListStandardGetLink
template<typename Element>
class DLListStandardGetLink {
private:
typedef DLListLink<Element> Link;
public:
inline Link *operator()(Element *element) const
{
return element->GetDLListLink();
}
inline const Link *operator()(const Element *element) const
{
return element->GetDLListLink();
}
};
// for convenience
#define DL_LIST_TEMPLATE_LIST template<typename Element, typename GetLink>
#define DL_LIST_CLASS_NAME DLList<Element, GetLink>
// DLList
template<typename Element, typename GetLink = DLListStandardGetLink<Element> >
class DLList {
private:
typedef DLListLink<Element> Link;
public:
DLList() : fFirst(NULL), fLast(NULL) {}
DLList(const GetLink &getLink)
: fFirst(NULL), fLast(NULL), fGetLink(getLink) {}
~DLList() {}
inline bool IsEmpty() const { return (fFirst == NULL); }
inline void Insert(Element *element, bool back = true);
inline void Remove(Element *element);
inline void Swap(Element *a, Element *b);
inline void MoveFrom(DL_LIST_CLASS_NAME *fromList);
inline void RemoveAll();
inline Element *GetFirst() const { return fFirst; }
inline Element *GetLast() const { return fLast; }
inline Element *GetHead() const { return fFirst; }
inline Element *GetTail() const { return fLast; }
inline Element *GetPrevious(Element *element) const;
inline Element *GetNext(Element *element) const;
private:
Element *fFirst;
Element *fLast;
GetLink fGetLink;
};
// inline methods
// Insert
DL_LIST_TEMPLATE_LIST
void
DL_LIST_CLASS_NAME::Insert(Element *element, bool back)
{
if (element) {
if (back) {
// append
Link *elLink = fGetLink(element);
elLink->previous = fLast;
elLink->next = NULL;
if (fLast)
fGetLink(fLast)->next = element;
else
fFirst = element;
fLast = element;
} else {
// prepend
Link *elLink = fGetLink(element);
elLink->previous = NULL;
elLink->next = fFirst;
if (fFirst)
fGetLink(fFirst)->previous = element;
else
fLast = element;
fFirst = element;
}
}
}
// Remove
DL_LIST_TEMPLATE_LIST
void
DL_LIST_CLASS_NAME::Remove(Element *element)
{
if (element) {
Link *elLink = fGetLink(element);
if (elLink->previous)
fGetLink(elLink->previous)->next = elLink->next;
else
fFirst = elLink->next;
if (elLink->next)
fGetLink(elLink->next)->previous = elLink->previous;
else
fLast = elLink->previous;
elLink->previous = NULL;
elLink->next = NULL;
}
}
// Swap
DL_LIST_TEMPLATE_LIST
void
DL_LIST_CLASS_NAME::Swap(Element *a, Element *b)
{
if (a && b && a != b) {
Link *aLink = fGetLink(a);
Link *bLink = fGetLink(b);
Element *aPrev = aLink->previous;
Element *bPrev = bLink->previous;
Element *aNext = aLink->next;
Element *bNext = bLink->next;
// place a
if (bPrev)
fGetLink(bPrev)->next = a;
else
fFirst = a;
if (bNext)
fGetLink(bNext)->previous = a;
else
fLast = a;
aLink->previous = bPrev;
aLink->next = bNext;
// place b
if (aPrev)
fGetLink(aPrev)->next = b;
else
fFirst = b;
if (aNext)
fGetLink(aNext)->previous = b;
else
fLast = b;
bLink->previous = aPrev;
bLink->next = aNext;
}
}
// MoveFrom
DL_LIST_TEMPLATE_LIST
void
DL_LIST_CLASS_NAME::MoveFrom(DL_LIST_CLASS_NAME *fromList)
{
if (fromList && fromList->fFirst) {
if (fFirst) {
fGetLink(fLast)->next = fromList->fFirst;
fGetLink(fFirst)->previous = fLast;
fLast = fromList->fLast;
} else {
fFirst = fromList->fFirst;
fLast = fromList->fLast;
}
fromList->fFirst = NULL;
fromList->fLast = NULL;
}
}
// RemoveAll
DL_LIST_TEMPLATE_LIST
void
DL_LIST_CLASS_NAME::RemoveAll()
{
Element *element = fFirst;
while (element) {
Link *elLink = fGetLink(element);
element = elLink->next;
elLink->previous = NULL;
elLink->next = NULL;
}
fFirst = NULL;
fLast = NULL;
}
// GetPrevious
DL_LIST_TEMPLATE_LIST
Element *
DL_LIST_CLASS_NAME::GetPrevious(Element *element) const
{
Element *result = NULL;
if (element)
result = fGetLink(element)->previous;
return result;
}
// GetNext
DL_LIST_TEMPLATE_LIST
Element *
DL_LIST_CLASS_NAME::GetNext(Element *element) const
{
Element *result = NULL;
if (element)
result = fGetLink(element)->next;
return result;
}
#endif // DL_LIST_H

View File

@ -306,7 +306,7 @@ D(if (!fVolume->CheckBlock(block, offset + size)) return NULL;);
D(
if (offset + size > kSmallDataContainerSize) {
FATAL(("DataContainer: Data access exceeds small buffer.\n"));
DEBUGGER("DataContainer: Data access exceeds small buffer.");
PANIC("DataContainer: Data access exceeds small buffer.");
return NULL;
}
);
@ -347,7 +347,7 @@ DataContainer::_ResizeLastBlock(size_t newSize)
D(
if (!_IsBlockMode()) {
FATAL(("Call of _ResizeLastBlock() in small buffer mode.\n"));
DEBUGGER("Call of _ResizeLastBlock() in small buffer mode.");
PANIC("Call of _ResizeLastBlock() in small buffer mode.");
return B_ERROR;
}
);

View File

@ -1,101 +0,0 @@
// Debug.cpp
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of a copyright holder shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization of the
// copyright holder.
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "Debug.h"
/*!
\file Debug.cpp
\brief Defines debug output function with printf() signature printing
into a file.
\note The initialization is not thread safe!
*/
// no need to define it, if not used
#if DEBUG_PRINT
static int32 init_counter = 0;
static int out = -1;
// init_debugging
status_t
init_debugging()
{
status_t error = B_OK;
if (init_counter++ == 0) {
// open the file
out = open(DEBUG_PRINT_FILE, O_RDWR | O_CREAT | O_TRUNC);
if (out < 0) {
error = errno;
init_counter--;
} else
dbg_printf("##################################################\n");
}
return error;
}
// exit_debugging
status_t
exit_debugging()
{
status_t error = B_OK;
if (out >= 0) {
if (--init_counter == 0) {
close(out);
out = -1;
}
} else
error = B_NO_INIT;
return error;
}
// dbg_printf
void
dbg_printf(const char *format,...)
{
char buffer[1024];
va_list args;
va_start(args, format);
// no vsnprintf() on PPC and in kernel
#if defined(__INTEL__) && USER
vsnprintf(buffer, sizeof(buffer) - 1, format, args);
#else
vsprintf(buffer, format, args);
#endif
va_end(args);
buffer[sizeof(buffer) - 1] = '\0';
write(out, buffer, strlen(buffer));
}
#endif // DEBUG_PRINT

View File

@ -1,117 +0,0 @@
#ifndef DEBUG_H
#define DEBUG_H
/* Debug - debug stuff
**
** Initial version by Axel Dörfler, axeld@pinc-software.de
** This file may be used under the terms of the OpenBeOS License.
*/
// Modified by Ingo Weinhold (bonefish@cs.tu-berlin.de)
#include <string.h>
#include <OS.h>
#include <SupportDefs.h>
// define all macros we work with -- undefined macros are set default
#ifndef USER
# define USER 0
#endif
#ifndef DEBUG
# define DEBUG 0
#endif
#if !DEBUG
# undef DEBUG_PRINT
# define DEBUG_PRINT 0
#endif
#ifndef DEBUG_PRINT
# define DEBUG_PRINT 0
#endif
#ifndef DEBUG_PRINT_FILE
# define DEBUG_PRINT_FILE "/var/log/reiserfs.log"
#endif
// define the debug output function
#if USER
# include <stdio.h>
# if DEBUG_PRINT
# define __out dbg_printf
# else
# define __out printf
# endif
#else
# include <KernelExport.h>
# include <null.h>
# if DEBUG_PRINT
# define __out dbg_printf
# else
# define __out dprintf
# endif
#endif
// functions exported by this module
#if DEBUG_PRINT
status_t init_debugging();
status_t exit_debugging();
void dbg_printf(const char *format,...);
#else
static inline status_t init_debugging() { return B_OK; }
static inline status_t exit_debugging() { return B_OK; }
static inline void dbg_printf(const char */*format*/,...) {}
#endif
// Short overview over the debug output macros:
// PRINT()
// is for general messages that very unlikely should appear in a release build
// FATAL()
// this is for fatal messages, when something has really gone wrong
// INFORM()
// general information, as disk size, etc.
// REPORT_ERROR(status_t)
// prints out error information
// RETURN_ERROR(status_t)
// calls REPORT_ERROR() and return the value
// D()
// the statements in D() are only included if DEBUG is defined
#define DEBUG_APP "ramfs"
#if DEBUG
#define PRINT(x) { __out(DEBUG_APP ": "); __out x; }
#define REPORT_ERROR(status) __out(DEBUG_APP ": %s:%d: %s\n",__FUNCTION__,__LINE__,strerror(status));
#define RETURN_ERROR(err) { status_t _status = err; if (_status < B_OK) REPORT_ERROR(_status); return _status;}
#define SET_ERROR(var, err) { status_t _status = err; if (_status < B_OK) REPORT_ERROR(_status); var = _status; }
#define FATAL(x) { __out(DEBUG_APP ": FATAL: "); __out x; }
#define INFORM(x) { __out(DEBUG_APP ": "); __out x; }
#define FUNCTION(x) { __out(DEBUG_APP ": %s() ",__FUNCTION__); __out x; }
#define FUNCTION_START() { __out(DEBUG_APP ": %s()\n",__FUNCTION__); }
#define FUNCTION_END() { __out(DEBUG_APP ": %s() done\n",__FUNCTION__); }
#define D(x) {x;};
#define DARG(x) x
#else
#define PRINT(x) ;
#define REPORT_ERROR(status) ;
#define RETURN_ERROR(status) return status;
#define SET_ERROR(var, err) var = err;
#define FATAL(x) { __out(DEBUG_APP ": FATAL: "); __out x; }
#define INFORM(x) { __out(DEBUG_APP ": "); __out x; }
#define FUNCTION(x) ;
#define FUNCTION_START() ;
#define FUNCTION_END() ;
#define D(x) ;
#define DARG(x)
#endif
#define TPRINT(x) { __out(DEBUG_APP ": "); __out x; }
#define TREPORT_ERROR(status) __out(DEBUG_APP ": %s:%d: %s\n",__FUNCTION__,__LINE__,strerror(status));
#define TRETURN_ERROR(err) { status_t _status = err; if (_status < B_OK) REPORT_ERROR(_status); return _status;}
#define TFUNCTION(x) { __out(DEBUG_APP ": %s() ",__FUNCTION__); __out x; }
#define TFUNCTION_START() { __out(DEBUG_APP ": %s()\n",__FUNCTION__); }
#define TFUNCTION_END() { __out(DEBUG_APP ": %s() done\n",__FUNCTION__); }
#if USER
#define DEBUGGER(x) debugger(x);
#else
// #define DEBUGGER(x)
#define DEBUGGER(x) debugger(x);
#endif
#endif /* DEBUG_H */

View File

@ -3,18 +3,33 @@ SubDir HAIKU_TOP src tests add-ons kernel file_systems userlandfs r5 src test
SetSubDirSupportedPlatforms r5 bone dano ;
local userlandFSTop = [ FDirName $(HAIKU_TOP) src tests add-ons kernel
file_systems userlandfs r5 ] ;
local userlandFSIncludes = [ FDirName $(userlandFSTop) headers ] ;
DEFINES += USER=1 ;
SubDirC++Flags -include
[ FDirName $(userlandFSIncludes) shared Compatibility.h ] ;
SubDirSysHdrs [ FDirName $(userlandFSIncludes) public ] ;
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
if $(OSPLAT) = X86 {
# SubDirC++Flags -include [ FDirName $(UFS_TOP) src kernel_add_on
# kernel-cpp.h ] ;
SubDirC++Flags -include [ FDirName $(SUBDIR) cpp.h ] ;
SubDirC++Flags -include [ FDirName $(SUBDIR) compatibility.h ] ;
}
SEARCH_SOURCE += [ FDirName $(userlandFSTop) src shared ] ;
Addon <test>ramfs
: # relpath - obsolete
: AllocationInfo.cpp
: Debug.cpp
Locker.cpp
String.cpp
AllocationInfo.cpp
AreaUtils.cpp
Attribute.cpp
AttributeIndex.cpp
@ -25,7 +40,6 @@ Addon <test>ramfs
BlockAllocatorAreaBucket.cpp
BlockReferenceManager.cpp
DataContainer.cpp
Debug.cpp
Directory.cpp
Entry.cpp
EntryIterator.cpp
@ -35,14 +49,12 @@ Addon <test>ramfs
IndexDirectory.cpp
kernel_interface.cpp
LastModifiedIndex.cpp
Locker.cpp
NameIndex.cpp
Node.cpp
NodeListener.cpp
NodeTable.cpp
Query.cpp
SizeIndex.cpp
String.cpp
SymLink.cpp
Volume.cpp
: false # is executable

View File

@ -1,297 +0,0 @@
//
// $Id: Locker.cpp,v 1.1 2002/07/09 12:24:49 ejakowatz Exp $
//
// This file contains the OpenBeOS implementation of BLocker.
//
#include "Locker.h"
#include <OS.h>
#include <SupportDefs.h>
#ifdef USE_OPENBEOS_NAMESPACE
namespace OpenBeOS {
#endif
//
// Data Member Documentation:
//
// The "fBenaphoreCount" member is set to 1 if the BLocker style is
// semaphore. If the style is benaphore, it is initialized to 0 and
// is incremented atomically when it is acquired, decremented when it
// is released. By setting the benaphore count to 1 when the style is
// semaphore, the benaphore effectively becomes a semaphore. I was able
// to determine this is what Be's implementation does by testing the
// result of the CountLockRequests() member.
//
// The "fSemaphoreID" member holds the sem_id returned from create_sem()
// when the BLocker is constructed. It is used to acquire and release
// the lock regardless of the lock style (semaphore or benaphore).
//
// The "fLockOwner" member holds the thread_id of the thread which
// currently holds the lock. If no thread holds the lock, it is set to
// B_ERROR.
//
// The "fRecursiveCount" member holds a count of the number of times the
// thread holding the lock has acquired the lock without a matching unlock.
// It is basically the number of times the thread must call Unlock() before
// the lock can be acquired by a different thread.
//
//
// Constructors:
//
// All constructors just pass their arguments to InitLocker(). Note that
// the default for "name" is "some BLocker" and "benaphore_style" is true.
//
BLocker::BLocker()
{
InitLocker("some BLocker", true);
}
BLocker::BLocker(const char *name)
{
InitLocker(name, true);
}
BLocker::BLocker(bool benaphore_style)
{
InitLocker("some BLocker", benaphore_style);
}
BLocker::BLocker(const char *name,
bool benaphore_style)
{
InitLocker(name, benaphore_style);
}
//
// This constructor is not documented. The final argument is ignored for
// now. In Be's headers, its called "for_IPC". DO NOT USE THIS
// CONSTRUCTOR!
//
BLocker::BLocker(const char *name,
bool benaphore_style,
bool)
{
InitLocker(name, benaphore_style);
}
//
// The destructor just deletes the semaphore. By deleting the semaphore,
// any threads waiting to acquire the BLocker will be unblocked.
//
BLocker::~BLocker()
{
delete_sem(fSemaphoreID);
}
bool
BLocker::Lock(void)
{
status_t result;
return (AcquireLock(B_INFINITE_TIMEOUT, &result));
}
status_t
BLocker::LockWithTimeout(bigtime_t timeout)
{
status_t result;
AcquireLock(timeout, &result);
return result;
}
void
BLocker::Unlock(void)
{
// If the thread currently holds the lockdecrement
if (IsLocked()) {
// Decrement the number of outstanding locks this thread holds
// on this BLocker.
fRecursiveCount--;
// If the recursive count is now at 0, that means the BLocker has
// been released by the thread.
if (fRecursiveCount == 0) {
// The BLocker is no longer owned by any thread.
fLockOwner = B_ERROR;
// Decrement the benaphore count and store the undecremented
// value in oldBenaphoreCount.
int32 oldBenaphoreCount = atomic_add(&fBenaphoreCount, -1);
// If the oldBenaphoreCount is greater than 1, then there is
// at lease one thread waiting for the lock in the case of a
// benaphore.
if (oldBenaphoreCount > 1) {
// Since there are threads waiting for the lock, it must
// be released. Note, the old benaphore count will always be
// greater than 1 for a semaphore so the release is always done.
release_sem(fSemaphoreID);
}
}
}
}
thread_id
BLocker::LockingThread(void) const
{
return fLockOwner;
}
bool
BLocker::IsLocked(void) const
{
// This member returns true if the calling thread holds the lock.
// The easiest way to determine this is to compare the result of
// find_thread() to the fLockOwner.
return (find_thread(NULL) == fLockOwner);
}
int32
BLocker::CountLocks(void) const
{
return fRecursiveCount;
}
int32
BLocker::CountLockRequests(void) const
{
return fBenaphoreCount;
}
sem_id
BLocker::Sem(void) const
{
return fSemaphoreID;
}
void
BLocker::InitLocker(const char *name,
bool benaphore)
{
if (benaphore) {
// Because this is a benaphore, initialize the benaphore count and
// create the semaphore. Because this is a benaphore, the semaphore
// count starts at 0 (ie acquired).
fBenaphoreCount = 0;
fSemaphoreID = create_sem(0, name);
} else {
// Because this is a semaphore, initialize the benaphore count to -1
// and create the semaphore. Because this is semaphore style, the
// semaphore count starts at 1 so that one thread can acquire it and
// the next thread to acquire it will block.
fBenaphoreCount = 1;
fSemaphoreID = create_sem(1, name);
}
// The lock is currently not acquired so there is no owner.
fLockOwner = B_ERROR;
// The lock is currently not acquired so the recursive count is zero.
fRecursiveCount = 0;
}
bool
BLocker::AcquireLock(bigtime_t timeout,
status_t *error)
{
// By default, return no error.
*error = B_NO_ERROR;
// Only try to acquire the lock if the thread doesn't already own it.
if (!IsLocked()) {
// Increment the benaphore count and test to see if it was already greater
// than 0. If it is greater than 0, then some thread already has the
// benaphore or the style is a semaphore. Either way, we need to acquire
// the semaphore in this case.
int32 oldBenaphoreCount = atomic_add(&fBenaphoreCount, 1);
if (oldBenaphoreCount > 0) {
*error = acquire_sem_etc(fSemaphoreID, 1, B_RELATIVE_TIMEOUT,
timeout);
// Note, if the lock here does time out, the benaphore count
// is not decremented. By doing this, the benaphore count will
// never go back to zero. This means that the locking essentially
// changes to semaphore style if this was a benaphore.
//
// Doing the decrement of the benaphore count when the acquisition
// fails is a risky thing to do. If you decrement the counter at
// the same time the thread which holds the benaphore does an
// Unlock(), there is serious risk of a race condition.
//
// If the Unlock() sees a positive count and releases the semaphore
// and then the timed out thread decrements the count to 0, there
// is no one to take the semaphore. The next two threads will be
// able to acquire the benaphore at the same time! The first will
// increment the counter and acquire the lock. The second will
// acquire the semaphore and therefore the lock. Not good.
//
// This has been discussed on the becodetalk mailing list and
// Trey from Be had this to say:
//
// I looked at the LockWithTimeout() code, and it does not have
// _this_ (ie the race condition) problem. It circumvents it by
// NOT doing the atomic_add(&count, -1) if the semaphore
// acquisition fails. This means that if a
// BLocker::LockWithTimeout() times out, all other Lock*() attempts
// turn into guaranteed semaphore grabs, _with_ the overhead of a
// (now) useless atomic_add().
//
// Given Trey's comments, it looks like Be took the same approach
// I did. The output of CountLockRequests() of Be's implementation
// confirms Trey's comments also.
//
// Finally some thoughts for the future with this code:
// - If 2^31 timeouts occur on a 32-bit machine (ie today),
// the benaphore count will wrap to a negative number. This
// would have unknown consequences on the ability of the BLocker
// to continue to function.
//
}
}
// If the lock has successfully been acquired.
if (*error == B_NO_ERROR) {
// Set the lock owner to this thread and increment the recursive count
// by one. The recursive count is incremented because one more Unlock()
// is now required to release the lock (ie, 0 => 1, 1 => 2 etc).
fLockOwner = find_thread(NULL);
fRecursiveCount++;
}
// Return true if the lock has been acquired.
return (*error == B_NO_ERROR);
}
#ifdef USE_OPENBEOS_NAMESPACE
}
#endif

View File

@ -1,63 +0,0 @@
//
// $Id: Locker.h,v 1.1 2002/07/09 12:24:33 ejakowatz Exp $
//
// This is the BLocker interface for OpenBeOS. It has been created to
// be source and binary compatible with the BeOS version of BLocker.
//
// bonefish: Removed virtual from destructor.
#ifndef _OPENBEOS_LOCKER_H
#define _OPENBEOS_LOCKER_H
#include <OS.h>
#include <SupportDefs.h>
#ifdef USE_OPENBEOS_NAMESPACE
namespace OpenBeOS {
#endif
class BLocker {
public:
BLocker();
BLocker(const char *name);
BLocker(bool benaphore_style);
BLocker(const char *name, bool benaphore_style);
// The following constructor is not documented in the BeBook
// and is only listed here to ensure binary compatibility.
// DO NOT USE THIS CONSTRUCTOR!
BLocker(const char *name, bool benaphore_style, bool);
~BLocker();
bool Lock(void);
status_t LockWithTimeout(bigtime_t timeout);
void Unlock(void);
thread_id LockingThread(void) const;
bool IsLocked(void) const;
int32 CountLocks(void) const;
int32 CountLockRequests(void) const;
sem_id Sem(void) const;
private:
void InitLocker(const char *name, bool benaphore_style);
bool AcquireLock(bigtime_t timeout, status_t *error);
int32 fBenaphoreCount;
sem_id fSemaphoreID;
thread_id fLockOwner;
int32 fRecursiveCount;
// Reserved space for future changes to BLocker
int32 fReservedSpace[4];
};
#ifdef USE_OPENBEOS_NAMESPACE
}
#endif
#endif // _OPENBEOS_LOCKER_H

View File

@ -3,118 +3,10 @@
#ifndef LOCKING_H
#define LOCKING_H
#include "AutoLocker.h"
class Volume;
// AutoLockerStandardLocking
template<typename Lockable>
class AutoLockerStandardLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->Lock();
}
inline void Unlock(Lockable *lockable)
{
lockable->Unlock();
}
};
// AutoLockerReadLocking
template<typename Lockable>
class AutoLockerReadLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->ReadLock();
}
inline void Unlock(Lockable *lockable)
{
lockable->ReadUnlock();
}
};
// AutoLockerWriteLocking
template<typename Lockable>
class AutoLockerWriteLocking {
public:
inline bool Lock(Lockable *lockable)
{
return lockable->WriteLock();
}
inline void Unlock(Lockable *lockable)
{
lockable->WriteUnlock();
}
};
// AutoLocker
template<typename Lockable,
typename Locking = AutoLockerStandardLocking<Lockable> >
class AutoLocker {
private:
typedef AutoLocker<Lockable, Locking> ThisClass;
public:
inline AutoLocker(Lockable *lockable)
: fLockable(lockable),
fLocked(false)
{
_Lock();
}
inline AutoLocker(Lockable &lockable)
: fLockable(&lockable),
fLocked(false)
{
_Lock();
}
inline ~AutoLocker()
{
_Unlock();
}
inline AutoLocker<Lockable, Locking> &operator=(Lockable *lockable)
{
_Unlock();
fLockable = lockable;
_Lock();
}
inline AutoLocker<Lockable, Locking> &operator=(Lockable &lockable)
{
_Unlock();
fLockable = &lockable;
_Lock();
}
inline bool IsLocked() const { return fLocked; }
inline operator bool() const { return fLocked; }
private:
inline void _Lock()
{
if (fLockable)
fLocked = fLocking.Lock(fLockable);
}
inline void _Unlock()
{
if (fLockable && fLocked) {
fLocking.Unlock(fLockable);
fLocked = false;
}
}
private:
Lockable *fLockable;
bool fLocked;
Locking fLocking;
};
// instantiations
typedef AutoLocker<Volume, AutoLockerReadLocking<Volume> > VolumeReadLocker;
typedef AutoLocker<Volume, AutoLockerWriteLocking<Volume> > VolumeWriteLocker;

View File

@ -30,6 +30,8 @@
#include <SupportDefs.h>
#include "String.h"
// min and max
// We don't want to include <algobase.h> otherwise we also get <iostream.h>
// and other undesired things.
@ -94,23 +96,6 @@ fls(uint32 value)
return index;
}
// string_hash
//
// from the Dragon Book: a slightly modified hashpjw()
static inline
uint32
string_hash(const char *name)
{
uint32 h = 0;
for (; *name; name++) {
uint32 g = h & 0xf0000000;
if (g)
h ^= g >> 24;
h = (h << 4) + *name;
}
return h;
}
// node_child_hash
static inline
uint32

View File

@ -1,148 +0,0 @@
// String.cpp
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// You can alternatively use *this file* under the terms of the the MIT
// license included in this package.
#include <new.h>
#include <string.h>
#include "String.h"
/*!
\class String
\brief A very simple string class.
*/
// constructor
String::String()
: fLength(0),
fString(NULL)
{
}
// copy constructor
String::String(const String &string)
: fLength(0),
fString(NULL)
{
*this = string;
}
// constructor
String::String(const char *string, int32 length)
: fLength(0),
fString(NULL)
{
SetTo(string, length);
}
// destructor
String::~String()
{
Unset();
}
// SetTo
bool
String::SetTo(const char *string, int32 maxLength)
{
if (string) {
if (maxLength > 0)
maxLength = strnlen(string, maxLength);
else if (maxLength < 0)
maxLength = strlen(string);
}
return _SetTo(string, maxLength);
}
// Unset
void
String::Unset()
{
if (fString) {
delete[] fString;
fString = NULL;
}
fLength = 0;
}
// Truncate
void
String::Truncate(int32 newLength)
{
if (newLength < 0)
newLength = 0;
if (newLength < fLength) {
char *string = fString;
int32 len = fLength;
fString = NULL;
len = 0;
if (!_SetTo(string, newLength)) {
fString = string;
fLength = newLength;
fString[fLength] = '\0';
} else
delete[] string;
}
}
// GetString
const char *
String::GetString() const
{
if (fString)
return fString;
return "";
}
// =
String &
String::operator=(const String &string)
{
if (&string != this)
_SetTo(string.fString, string.fLength);
return *this;
}
// ==
bool
String::operator==(const String &string) const
{
return (fLength == string.fLength
&& (fLength == 0 || !strcmp(fString, string.fString)));
}
// _SetTo
bool
String::_SetTo(const char *string, int32 length)
{
bool result = true;
Unset();
if (string && length > 0) {
fString = new(nothrow) char[length + 1];
if (fString) {
memcpy(fString, string, length);
fString[length] = '\0';
fLength = length;
} else
result = false;
}
return result;
}

View File

@ -1,58 +0,0 @@
// String.h
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// You can alternatively use *this file* under the terms of the the MIT
// license included in this package.
#ifndef STRING_H
#define STRING_H
#include <SupportDefs.h>
#ifdef __cplusplus
class String {
public:
String();
String(const String &string);
String(const char *string, int32 length = -1);
~String();
bool SetTo(const char *string, int32 maxLength = -1);
void Unset();
void Truncate(int32 newLength);
const char *GetString() const;
int32 GetLength() const { return fLength; }
String &operator=(const String &string);
bool operator==(const String &string) const;
bool operator!=(const String &string) const { return !(*this == string); }
private:
bool _SetTo(const char *string, int32 length);
private:
int32 fLength;
char *fString;
};
#endif // __cplusplus
#endif // STRING_H

View File

@ -181,8 +181,8 @@ private:
IndexDirectory *fIndexDirectory;
Directory *fRootDirectory;
String fName;
BLocker fLocker;
BLocker fIteratorLocker;
Locker fLocker;
Locker fIteratorLocker;
NodeListenerTree *fNodeListeners;
NodeListenerList fAnyNodeListeners;
EntryListenerTree *fEntryListeners;

View File

@ -1,46 +0,0 @@
// compatibility.h
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// You can alternatively use *this file* under the terms of the the MIT
// license included in this package.
#ifndef RAMFS_COMPATIBILITY_H
#define RAMFS_COMPATIBILITY_H
#include <BeBuild.h>
#if B_BEOS_VERSION <= B_BEOS_VERSION_5
//# define B_BAD_DATA -2147483632L
#else
# ifndef closesocket
# define closesocket(fd) close(fd)
# endif
# define _IMPEXP_KERNEL
#endif
// a Haiku definition
#ifndef B_BUFFER_OVERFLOW
# define B_BUFFER_OVERFLOW EOVERFLOW
#endif
// make Zeta R5 source compatible without needing to link against libzeta.so
#ifdef find_directory
# undef find_directory
#endif
#endif // RAMFS_COMPATIBILITY_H

View File

@ -1,249 +0,0 @@
#ifndef _FSPROTO_H
#define _FSPROTO_H
#include <sys/dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iovec.h>
#include <OS.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <BeBuild.h>
#include <Drivers.h>
typedef dev_t nspace_id;
typedef ino_t vnode_id;
/*
* PUBLIC PART OF THE FILE SYSTEM PROTOCOL
*/
#define WSTAT_MODE 0x0001
#define WSTAT_UID 0x0002
#define WSTAT_GID 0x0004
#define WSTAT_SIZE 0x0008
#define WSTAT_ATIME 0x0010
#define WSTAT_MTIME 0x0020
#define WSTAT_CRTIME 0x0040
#define WFSSTAT_NAME 0x0001
#define B_ENTRY_CREATED 1
#define B_ENTRY_REMOVED 2
#define B_ENTRY_MOVED 3
#define B_STAT_CHANGED 4
#define B_ATTR_CHANGED 5
#define B_DEVICE_MOUNTED 6
#define B_DEVICE_UNMOUNTED 7
#define B_STOP_WATCHING 0x0000
#define B_WATCH_NAME 0x0001
#define B_WATCH_STAT 0x0002
#define B_WATCH_ATTR 0x0004
#define B_WATCH_DIRECTORY 0x0008
#define SELECT_READ 1
#define SELECT_WRITE 2
#define SELECT_EXCEPTION 3
#define B_CUR_FS_API_VERSION 2
struct attr_info;
struct index_info;
typedef int op_read_vnode(void *ns, vnode_id vnid, char r, void **node);
typedef int op_write_vnode(void *ns, void *node, char r);
typedef int op_remove_vnode(void *ns, void *node, char r);
typedef int op_secure_vnode(void *ns, void *node);
typedef int op_walk(void *ns, void *base, const char *file, char **newpath,
vnode_id *vnid);
typedef int op_access(void *ns, void *node, int mode);
typedef int op_create(void *ns, void *dir, const char *name,
int omode, int perms, vnode_id *vnid, void **cookie);
typedef int op_mkdir(void *ns, void *dir, const char *name, int perms);
typedef int op_symlink(void *ns, void *dir, const char *name,
const char *path);
typedef int op_link(void *ns, void *dir, const char *name, void *node);
typedef int op_rename(void *ns, void *olddir, const char *oldname,
void *newdir, const char *newname);
typedef int op_unlink(void *ns, void *dir, const char *name);
typedef int op_rmdir(void *ns, void *dir, const char *name);
typedef int op_readlink(void *ns, void *node, char *buf, size_t *bufsize);
typedef int op_opendir(void *ns, void *node, void **cookie);
typedef int op_closedir(void *ns, void *node, void *cookie);
typedef int op_rewinddir(void *ns, void *node, void *cookie);
typedef int op_readdir(void *ns, void *node, void *cookie, long *num,
struct dirent *buf, size_t bufsize);
typedef int op_open(void *ns, void *node, int omode, void **cookie);
typedef int op_close(void *ns, void *node, void *cookie);
typedef int op_free_cookie(void *ns, void *node, void *cookie);
typedef int op_read(void *ns, void *node, void *cookie, off_t pos, void *buf,
size_t *len);
typedef int op_write(void *ns, void *node, void *cookie, off_t pos,
const void *buf, size_t *len);
typedef int op_readv(void *ns, void *node, void *cookie, off_t pos, const iovec *vec,
size_t count, size_t *len);
typedef int op_writev(void *ns, void *node, void *cookie, off_t pos, const iovec *vec,
size_t count, size_t *len);
typedef int op_ioctl(void *ns, void *node, void *cookie, int cmd, void *buf,
size_t len);
typedef int op_setflags(void *ns, void *node, void *cookie, int flags);
typedef int op_rstat(void *ns, void *node, struct stat *);
typedef int op_wstat(void *ns, void *node, struct stat *, long mask);
typedef int op_fsync(void *ns, void *node);
typedef int op_select(void *ns, void *node, void *cookie, uint8 event,
uint32 ref, selectsync *sync);
typedef int op_deselect(void *ns, void *node, void *cookie, uint8 event,
selectsync *sync);
typedef int op_initialize(const char *devname, void *parms, size_t len);
typedef int op_mount(nspace_id nsid, const char *devname, ulong flags,
void *parms, size_t len, void **data, vnode_id *vnid);
typedef int op_unmount(void *ns);
typedef int op_sync(void *ns);
typedef int op_rfsstat(void *ns, struct fs_info *);
typedef int op_wfsstat(void *ns, struct fs_info *, long mask);
typedef int op_open_attrdir(void *ns, void *node, void **cookie);
typedef int op_close_attrdir(void *ns, void *node, void *cookie);
typedef int op_rewind_attrdir(void *ns, void *node, void *cookie);
typedef int op_read_attrdir(void *ns, void *node, void *cookie, long *num,
struct dirent *buf, size_t bufsize);
typedef int op_remove_attr(void *ns, void *node, const char *name);
typedef int op_rename_attr(void *ns, void *node, const char *oldname,
const char *newname);
typedef int op_stat_attr(void *ns, void *node, const char *name,
struct attr_info *buf);
typedef int op_write_attr(void *ns, void *node, const char *name, int type,
const void *buf, size_t *len, off_t pos);
typedef int op_read_attr(void *ns, void *node, const char *name, int type,
void *buf, size_t *len, off_t pos);
typedef int op_open_indexdir(void *ns, void **cookie);
typedef int op_close_indexdir(void *ns, void *cookie);
typedef int op_rewind_indexdir(void *ns, void *cookie);
typedef int op_read_indexdir(void *ns, void *cookie, long *num,
struct dirent *buf, size_t bufsize);
typedef int op_create_index(void *ns, const char *name, int type, int flags);
typedef int op_remove_index(void *ns, const char *name);
typedef int op_rename_index(void *ns, const char *oldname,
const char *newname);
typedef int op_stat_index(void *ns, const char *name, struct index_info *buf);
typedef int op_open_query(void *ns, const char *query, ulong flags,
port_id port, long token, void **cookie);
typedef int op_close_query(void *ns, void *cookie);
typedef int op_read_query(void *ns, void *cookie, long *num,
struct dirent *buf, size_t bufsize);
typedef struct vnode_ops {
op_read_vnode (*read_vnode);
op_write_vnode (*write_vnode);
op_remove_vnode (*remove_vnode);
op_secure_vnode (*secure_vnode);
op_walk (*walk);
op_access (*access);
op_create (*create);
op_mkdir (*mkdir);
op_symlink (*symlink);
op_link (*link);
op_rename (*rename);
op_unlink (*unlink);
op_rmdir (*rmdir);
op_readlink (*readlink);
op_opendir (*opendir);
op_closedir (*closedir);
op_free_cookie (*free_dircookie);
op_rewinddir (*rewinddir);
op_readdir (*readdir);
op_open (*open);
op_close (*close);
op_free_cookie (*free_cookie);
op_read (*read);
op_write (*write);
op_readv (*readv);
op_writev (*writev);
op_ioctl (*ioctl);
op_setflags (*setflags);
op_rstat (*rstat);
op_wstat (*wstat);
op_fsync (*fsync);
op_initialize (*initialize);
op_mount (*mount);
op_unmount (*unmount);
op_sync (*sync);
op_rfsstat (*rfsstat);
op_wfsstat (*wfsstat);
op_select (*select);
op_deselect (*deselect);
op_open_indexdir (*open_indexdir);
op_close_indexdir (*close_indexdir);
op_free_cookie (*free_indexdircookie);
op_rewind_indexdir (*rewind_indexdir);
op_read_indexdir (*read_indexdir);
op_create_index (*create_index);
op_remove_index (*remove_index);
op_rename_index (*rename_index);
op_stat_index (*stat_index);
op_open_attrdir (*open_attrdir);
op_close_attrdir (*close_attrdir);
op_free_cookie (*free_attrdircookie);
op_rewind_attrdir (*rewind_attrdir);
op_read_attrdir (*read_attrdir);
op_write_attr (*write_attr);
op_read_attr (*read_attr);
op_remove_attr (*remove_attr);
op_rename_attr (*rename_attr);
op_stat_attr (*stat_attr);
op_open_query (*open_query);
op_close_query (*close_query);
op_free_cookie (*free_querycookie);
op_read_query (*read_query);
} vnode_ops;
#ifdef __cplusplus
extern "C" {
#endif
extern _IMPEXP_KERNEL int new_path(const char *path, char **copy);
extern _IMPEXP_KERNEL void free_path(char *p);
extern _IMPEXP_KERNEL int notify_listener(int op, nspace_id nsid,
vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name);
extern _IMPEXP_KERNEL void notify_select_event(selectsync *sync, uint32 ref);
extern _IMPEXP_KERNEL int send_notification(port_id port, long token,
ulong what, long op, nspace_id nsida,
nspace_id nsidb, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc,
const char *name);
extern _IMPEXP_KERNEL int get_vnode(nspace_id nsid, vnode_id vnid, void **data);
extern _IMPEXP_KERNEL int put_vnode(nspace_id nsid, vnode_id vnid);
extern _IMPEXP_KERNEL int new_vnode(nspace_id nsid, vnode_id vnid, void *data);
extern _IMPEXP_KERNEL int remove_vnode(nspace_id nsid, vnode_id vnid);
extern _IMPEXP_KERNEL int unremove_vnode(nspace_id nsid, vnode_id vnid);
extern _IMPEXP_KERNEL int is_vnode_removed(nspace_id nsid, vnode_id vnid);
extern _EXPORT vnode_ops fs_entry;
extern _EXPORT int32 api_version;
#ifdef __cplusplus
} // extern "C"
#endif
#endif