aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/experimental/debugmutex.cpp78
-rw-r--r--src/experimental/debugmutex.h102
-rw-r--r--src/stable/mutex.h8
-rw-r--r--src/stable/myriad.cpp34
-rw-r--r--src/stable/myriad.h49
-rw-r--r--src/tests/myriadfs.cpp2
-rw-r--r--src/unstable/myriadcache.h4
-rw-r--r--src/unstable/myriadfs.cpp30
-rw-r--r--src/unstable/myriadfs.h14
9 files changed, 288 insertions, 33 deletions
diff --git a/src/experimental/debugmutex.cpp b/src/experimental/debugmutex.cpp
new file mode 100644
index 0000000..2b61ae2
--- /dev/null
+++ b/src/experimental/debugmutex.cpp
@@ -0,0 +1,78 @@
1#include "bu/debugmutex.h"
2
3#include "bu/exceptionbase.h"
4
5Bu::DebugMutex::DebugMutex()
6{
7}
8
9Bu::DebugMutex::~DebugMutex()
10{
11}
12
13int Bu::DebugMutex::lock()
14{
15 pthread_t self = pthread_self();
16 mState.lock();
17 bool bFound = false;
18 for( ThreadList::iterator i = lThreads.begin(); i; i++ )
19 {
20 if( (*i) == self )
21 {
22 bFound = true;
23 if( (*i).bLocked == true )
24 {
25 throw Bu::ExceptionBase( Bu::String("Double lock in thread: %1").arg( (*i).sName ).end().getStr() );
26
27 }
28 else
29 {
30 (*i).bLocked = true;
31 }
32 break;
33 }
34 }
35 if( bFound == false )
36 {
37 lThreads.append( ThreadInfo( true ) );
38 }
39 mState.unlock();
40 return Bu::Mutex::lock();
41}
42
43int Bu::DebugMutex::unlock()
44{
45 pthread_t self = pthread_self();
46 mState.lock();
47 bool bFound = false;
48 for( ThreadList::iterator i = lThreads.begin(); i; i++ )
49 {
50 if( (*i) == self )
51 {
52 bFound = true;
53 if( (*i).bLocked == false )
54 {
55 throw Bu::ExceptionBase( Bu::String("Unlock in thread that did not lock: %1").arg( (*i).sName ).end().getStr() );
56
57 }
58 else
59 {
60 (*i).bLocked = false;
61 }
62 break;
63 }
64 }
65 if( bFound == false )
66 {
67 ThreadInfo info( false );
68 throw Bu::ExceptionBase( Bu::String("Unlock in thread that never locked mutex: %1").arg( info.sName ).end().getStr() );
69 }
70 mState.unlock();
71 return Bu::Mutex::unlock();
72}
73
74int Bu::DebugMutex::trylock()
75{
76 return Bu::Mutex::trylock();
77}
78
diff --git a/src/experimental/debugmutex.h b/src/experimental/debugmutex.h
new file mode 100644
index 0000000..ca8ef9f
--- /dev/null
+++ b/src/experimental/debugmutex.h
@@ -0,0 +1,102 @@
1/*
2 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_DEBUG_MUTEX_H
9#define BU_DEBUG_MUTEX_H
10
11#include "bu/mutex.h"
12#include "bu/list.h"
13#include "bu/string.h"
14
15namespace Bu
16{
17 /**
18 * Simple mutex wrapper. Currently this doesn't do anything extra for you
19 * except keep all of the functionality together in an OO sorta' way and
20 * keep you from having to worry about cleaning up your mutexes properly,
21 * or initing them.
22 *@ingroup Threading
23 */
24 class DebugMutex : public Mutex
25 {
26 public:
27 /**
28 * Create an unlocked mutex.
29 */
30 DebugMutex();
31
32 /**
33 * Destroy a mutex. This can only be done when a mutex is unlocked.
34 * Failure to unlock before destroying a mutex object could cause it to
35 * wait for the mutex to unlock, the odds of which are usually farily
36 * low at deconstruction time.
37 */
38 virtual ~DebugMutex();
39
40 /**
41 * Lock the mutex. This causes all future calls to lock on this
42 * instance of mutex to block until the first thread that called mutex
43 * unlocks it. At that point the next thread that called lock will get
44 * a chance to go to work. Because of the nature of a mutex lock it is
45 * a very bad idea to do any kind of serious or rather time consuming
46 * computation within a locked section. This can cause thread-deadlock
47 * and your program may hang.
48 */
49 virtual int lock();
50
51 /**
52 * Unlock the mutex. This allows the next thread that asked for a lock
53 * to lock the mutex and continue with execution.
54 */
55 virtual int unlock();
56
57 /**
58 * Try to lock the mutex. This is the option to go with if you cannot
59 * avoid putting lengthy operations within a locked section. trylock
60 * will attempt to lock the mutex, if the mutex is already locked this
61 * function returns immediately with an error code.
62 */
63 virtual int trylock();
64
65 private:
66 Bu::Mutex mState;
67
68 class ThreadInfo
69 {
70 public:
71 ThreadInfo( bool bLocked=false ) :
72 idThread( pthread_self() ),
73 bLocked( bLocked )
74 {
75 char buf[64];
76 if( pthread_getname_np( idThread, buf, 64 ) == 0 )
77 sName = buf;
78 }
79 ~ThreadInfo() {}
80
81 bool operator==( const ThreadInfo &rhs )
82 {
83 return pthread_equal( idThread, rhs.idThread );
84 }
85
86 bool operator==( const pthread_t &rhs )
87 {
88 return pthread_equal( idThread, rhs );
89 }
90
91 pthread_t idThread;
92 Bu::String sName;
93 bool bLocked;
94 };
95 typedef Bu::List<ThreadInfo> ThreadList;
96 ThreadList lThreads;
97 };
98}
99
100#endif
101
102
diff --git a/src/stable/mutex.h b/src/stable/mutex.h
index d9e8910..8034974 100644
--- a/src/stable/mutex.h
+++ b/src/stable/mutex.h
@@ -33,7 +33,7 @@ namespace Bu
33 * wait for the mutex to unlock, the odds of which are usually farily 33 * wait for the mutex to unlock, the odds of which are usually farily
34 * low at deconstruction time. 34 * low at deconstruction time.
35 */ 35 */
36 ~Mutex(); 36 virtual ~Mutex();
37 37
38 /** 38 /**
39 * Lock the mutex. This causes all future calls to lock on this 39 * Lock the mutex. This causes all future calls to lock on this
@@ -44,13 +44,13 @@ namespace Bu
44 * computation within a locked section. This can cause thread-deadlock 44 * computation within a locked section. This can cause thread-deadlock
45 * and your program may hang. 45 * and your program may hang.
46 */ 46 */
47 int lock(); 47 virtual int lock();
48 48
49 /** 49 /**
50 * Unlock the mutex. This allows the next thread that asked for a lock 50 * Unlock the mutex. This allows the next thread that asked for a lock
51 * to lock the mutex and continue with execution. 51 * to lock the mutex and continue with execution.
52 */ 52 */
53 int unlock(); 53 virtual int unlock();
54 54
55 /** 55 /**
56 * Try to lock the mutex. This is the option to go with if you cannot 56 * Try to lock the mutex. This is the option to go with if you cannot
@@ -58,7 +58,7 @@ namespace Bu
58 * will attempt to lock the mutex, if the mutex is already locked this 58 * will attempt to lock the mutex, if the mutex is already locked this
59 * function returns immediately with an error code. 59 * function returns immediately with an error code.
60 */ 60 */
61 int trylock(); 61 virtual int trylock();
62 62
63 protected: 63 protected:
64 pthread_mutex_t mutex; /**< The internal mutex reference. */ 64 pthread_mutex_t mutex; /**< The internal mutex reference. */
diff --git a/src/stable/myriad.cpp b/src/stable/myriad.cpp
index 03cffa9..492676e 100644
--- a/src/stable/myriad.cpp
+++ b/src/stable/myriad.cpp
@@ -129,6 +129,19 @@ Bu::MyriadStream Bu::Myriad::open( Bu::Myriad::StreamId iStream,
129 return Bu::MyriadStream( *this, pStream, eMode ); 129 return Bu::MyriadStream( *this, pStream, eMode );
130} 130}
131 131
132Bu::Myriad::StreamId Bu::Myriad::allocate()
133{
134 Bu::MutexLocker l( mAccess );
135
136 Stream *pStream = new Stream( *this, ++iLastUsedIndex, 0 );
137 mhStream.lock();
138 hStream.insert( pStream->iStream, pStream );
139 mhStream.unlock();
140 bStructureChanged = true;
141
142 return pStream->iStream;
143}
144
132void Bu::Myriad::erase( Bu::Myriad::StreamId iStream ) 145void Bu::Myriad::erase( Bu::Myriad::StreamId iStream )
133{ 146{
134 // For now, let's prevent you from erasing a stream if it's open. 147 // For now, let's prevent you from erasing a stream if it's open.
@@ -252,6 +265,19 @@ int32_t Bu::Myriad::getTotalUnusedBytes(int32_t iAssumeBlockSize ) const
252 return iTotal; 265 return iTotal;
253} 266}
254 267
268Bu::Myriad::StreamIdList Bu::Myriad::getStreamList() const
269{
270 mhStream.lock();
271 StreamIdList lIds = hStream.getKeys();
272 mhStream.unlock();
273 lIds.sort();
274 if( lIds.first() == 0 )
275 {
276 lIds.eraseFirst();
277 }
278 return lIds;
279}
280
255Bu::BitString Bu::Myriad::buildBlockUseMap() const 281Bu::BitString Bu::Myriad::buildBlockUseMap() const
256{ 282{
257 Bu::MutexLocker l( mAccess ); 283 Bu::MutexLocker l( mAccess );
@@ -264,10 +290,10 @@ Bu::BitString Bu::Myriad::buildBlockUseMap() const
264 return bsMap; 290 return bsMap;
265} 291}
266 292
267Bu::Array<int32_t> Bu::Myriad::buildBlockMap() const 293Bu::Myriad::StreamIdArray Bu::Myriad::buildBlockMap() const
268{ 294{
269 Bu::MutexLocker l( mAccess ); 295 Bu::MutexLocker l( mAccess );
270 Bu::Array<int32_t> bm( iBlockCount ); 296 StreamIdArray bm( iBlockCount );
271 for( int j = 0; j < iBlockCount; j++ ) 297 for( int j = 0; j < iBlockCount; j++ )
272 { 298 {
273 bm.append( -1 ); 299 bm.append( -1 );
@@ -768,9 +794,7 @@ int32_t Bu::Myriad::Stream::read( int32_t iStart, void *pTarget,
768 794
769 if( iStart+iSize >= this->iSize ) 795 if( iStart+iSize >= this->iSize )
770 { 796 {
771 int32_t iDiff = (iStart+iSize)-this->iSize; 797 iSize = this->iSize-iStart;
772 iSize -= iDiff;
773 iStart += iDiff;
774 } 798 }
775 799
776 while( iSize > 0 ) 800 while( iSize > 0 )
diff --git a/src/stable/myriad.h b/src/stable/myriad.h
index 6168aa2..5accd1e 100644
--- a/src/stable/myriad.h
+++ b/src/stable/myriad.h
@@ -31,10 +31,20 @@ namespace Bu
31 }; 31 };
32 subExceptionDeclEnd(); 32 subExceptionDeclEnd();
33 33
34 /**
35 * Myriad Stream Multiplexer. This is a system that allows you to store
36 * many streams within a single backing stream. This is great for databases,
37 * caching, etc. It's fairly lightweight, and allows all streams to grow
38 * dynamically using a block-allocation scheme. This is used extensively
39 * by the caching system and MyriadFs as well as other systems within
40 * libbu++.
41 */
34 class Myriad 42 class Myriad
35 { 43 {
36 public: 44 public:
37 typedef int32_t StreamId; 45 typedef int32_t StreamId;
46 typedef Bu::Array<StreamId> StreamIdArray;
47 typedef Bu::List<StreamId> StreamIdList;
38 enum Mode : int32_t { 48 enum Mode : int32_t {
39 None = 0x00, 49 None = 0x00,
40 50
@@ -55,8 +65,9 @@ namespace Bu
55 65
56 public: 66 public:
57 /** 67 /**
58 * Open existing Myriad stream, or initialize a new one if it doesn't 68 * Open existing Myriad container, or initialize a new one if the
59 * exist. 69 * backing stream is empty. If other data is already in the provided
70 * backing stream an error is thrown.
60 * 71 *
61 * Myriad format V0 72 * Myriad format V0
62 * 0 - 3: Myriad_MAGIC_CODE (0ad3fa84) 73 * 0 - 3: Myriad_MAGIC_CODE (0ad3fa84)
@@ -75,8 +86,32 @@ namespace Bu
75 int32_t iPreallocateBlocks=-1 ); 86 int32_t iPreallocateBlocks=-1 );
76 virtual ~Myriad(); 87 virtual ~Myriad();
77 88
89 /**
90 * Creates a new stream open in the specified eMode and, optionally,
91 * preallocates the specificed amount of space. The stream is zero
92 * bytes even if space is preallocated. The open stream is returned,
93 * ready for use. Use this if you don't care what the id is of the
94 * newly created stream.
95 */
78 MyriadStream create( Mode eMode, int32_t iPreallocateBytes=-1 ); 96 MyriadStream create( Mode eMode, int32_t iPreallocateBytes=-1 );
97
98 /**
99 * Open an existing stream or create a new stream with the specified
100 * id (iStream) with the specified eMode. This respects the normal file
101 * modes, see Bu::Myriad::Mode for details.
102 */
79 MyriadStream open( StreamId iStream, Mode eMode ); 103 MyriadStream open( StreamId iStream, Mode eMode );
104
105 /**
106 * Allocate a new stream but do not open it, just ensure it exists and
107 * return the id of the newly allocated stream.
108 */
109 StreamId allocate();
110
111 /**
112 * Erase the stream specified by iStream. This only can work when the
113 * stream is not open at the moment.
114 */
80 void erase( StreamId iStream ); 115 void erase( StreamId iStream );
81 void setSize( StreamId iStream, int32_t iNewSize ); 116 void setSize( StreamId iStream, int32_t iNewSize );
82 int32_t getSize( StreamId iStream ) const; 117 int32_t getSize( StreamId iStream ) const;
@@ -90,7 +125,15 @@ namespace Bu
90 int32_t getTotalUsedBytes() const; 125 int32_t getTotalUsedBytes() const;
91 int32_t getTotalUnusedBytes( int32_t iAssumeBlockSize=-1 ) const; 126 int32_t getTotalUnusedBytes( int32_t iAssumeBlockSize=-1 ) const;
92 Bu::BitString buildBlockUseMap() const; 127 Bu::BitString buildBlockUseMap() const;
93 Bu::Array<int32_t> buildBlockMap() const; 128 StreamIdArray buildBlockMap() const;
129
130 /**
131 * Lists all stream ids that you are allowed to open. Technically there
132 * is always a zero stream, but it is used by Myriad for stream/block
133 * accounting. It works like a normal stream but you should not open
134 * it.
135 */
136 StreamIdList getStreamList() const;
94 137
95 /** 138 /**
96 * Flush all caches to the backing stream, write all structural and 139 * Flush all caches to the backing stream, write all structural and
diff --git a/src/tests/myriadfs.cpp b/src/tests/myriadfs.cpp
index 1266e4b..29ac3d9 100644
--- a/src/tests/myriadfs.cpp
+++ b/src/tests/myriadfs.cpp
@@ -9,7 +9,7 @@ using namespace Bu;
9int main() 9int main()
10{ 10{
11// Bu::MemBuf mb; 11// Bu::MemBuf mb;
12 Bu::File mb("store.myr", File::Read|File::Write|File::Create ); 12 Bu::File mb("store.mfs", File::Read|File::Write|File::Create );
13 Bu::MyriadFs mfs( mb, 512 ); 13 Bu::MyriadFs mfs( mb, 512 );
14 14
15 sio << "Creating dirs..." << sio.nl; 15 sio << "Creating dirs..." << sio.nl;
diff --git a/src/unstable/myriadcache.h b/src/unstable/myriadcache.h
index d6842a5..f71f9b5 100644
--- a/src/unstable/myriadcache.h
+++ b/src/unstable/myriadcache.h
@@ -86,8 +86,8 @@ namespace Bu
86 { 86 {
87 Bu::ReadWriteMutex::WriteLocker wl( rwStore ); 87 Bu::ReadWriteMutex::WriteLocker wl( rwStore );
88 { 88 {
89 Bu::MyriadStream ms = mStore.create( Bu::Myriad::Create ); 89 Bu::Myriad::StreamId id = mStore.allocate();
90 hIndex.insert( o->getKey(), ms.getId() ); 90 hIndex.insert( o->getKey(), id );
91 } 91 }
92 _save( o ); 92 _save( o );
93 93
diff --git a/src/unstable/myriadfs.cpp b/src/unstable/myriadfs.cpp
index ab9ca74..f748a53 100644
--- a/src/unstable/myriadfs.cpp
+++ b/src/unstable/myriadfs.cpp
@@ -8,6 +8,7 @@
8#include "bu/config.h" 8#include "bu/config.h"
9#include "bu/myriadfs.h" 9#include "bu/myriadfs.h"
10#include "bu/myriadstream.h" 10#include "bu/myriadstream.h"
11#include "bu/mutexlocker.h"
11 12
12#include <string.h> 13#include <string.h>
13#include <unistd.h> 14#include <unistd.h>
@@ -107,6 +108,7 @@ Bu::MyriadFs::~MyriadFs()
107 108
108void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf ) 109void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf )
109{ 110{
111 Bu::MutexLocker lLock( mAccess );
110 int32_t iParent; 112 int32_t iParent;
111 int32_t iNode = lookupInode( sPath, iParent ); 113 int32_t iNode = lookupInode( sPath, iParent );
112 Bu::MyriadStream is = mStore.open( 2, Bu::Myriad::Read ); 114 Bu::MyriadStream is = mStore.open( 2, Bu::Myriad::Read );
@@ -116,6 +118,7 @@ void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf )
116Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode, 118Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode,
117 uint16_t uPerms ) 119 uint16_t uPerms )
118{ 120{
121 Bu::MutexLocker lLock( mAccess );
119 int32_t iParent = -1; 122 int32_t iParent = -1;
120 int32_t iNode; 123 int32_t iNode;
121 try 124 try
@@ -164,6 +167,7 @@ void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms,
164void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, 167void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms,
165 uint32_t uSpecial ) 168 uint32_t uSpecial )
166{ 169{
170 Bu::MutexLocker lLock( mAccess );
167 int32_t iParent = -1; 171 int32_t iParent = -1;
168// int32_t iNode; 172// int32_t iNode;
169 try 173 try
@@ -200,6 +204,7 @@ void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms )
200void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget, 204void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget,
201 const Bu::String &sPath ) 205 const Bu::String &sPath )
202{ 206{
207 Bu::MutexLocker lLock( mAccess );
203 int32_t iParent = -1; 208 int32_t iParent = -1;
204 int32_t iNode; 209 int32_t iNode;
205 try 210 try
@@ -232,6 +237,7 @@ void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget,
232void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget, 237void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget,
233 const Bu::String &sPath ) 238 const Bu::String &sPath )
234{ 239{
240 Bu::MutexLocker lLock( mAccess );
235 int32_t iParent = -1; 241 int32_t iParent = -1;
236 int32_t iNode; 242 int32_t iNode;
237 243
@@ -267,6 +273,7 @@ void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget,
267 273
268Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath ) 274Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath )
269{ 275{
276 Bu::MutexLocker lLock( mAccess );
270 int32_t iParent = -1; 277 int32_t iParent = -1;
271 int32_t iNode; 278 int32_t iNode;
272 iNode = lookupInode( sPath, iParent ); 279 iNode = lookupInode( sPath, iParent );
@@ -279,6 +286,7 @@ Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath )
279 286
280Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath ) 287Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath )
281{ 288{
289 Bu::MutexLocker lLock( mAccess );
282 int32_t iParent = -1; 290 int32_t iParent = -1;
283 int32_t iNode = lookupInode( sPath, iParent ); 291 int32_t iNode = lookupInode( sPath, iParent );
284 return readDir( iNode ); 292 return readDir( iNode );
@@ -287,6 +295,7 @@ Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath )
287void Bu::MyriadFs::setTimes( const Bu::String &sPath, int64_t iATime, 295void Bu::MyriadFs::setTimes( const Bu::String &sPath, int64_t iATime,
288 int64_t iMTime ) 296 int64_t iMTime )
289{ 297{
298 Bu::MutexLocker lLock( mAccess );
290 int32_t iParent = -1; 299 int32_t iParent = -1;
291 int32_t iNode; 300 int32_t iNode;
292 301
@@ -297,6 +306,7 @@ void Bu::MyriadFs::setTimes( const Bu::String &sPath, int64_t iATime,
297 306
298void Bu::MyriadFs::unlink( const Bu::String &sPath ) 307void Bu::MyriadFs::unlink( const Bu::String &sPath )
299{ 308{
309 Bu::MutexLocker lLock( mAccess );
300 int32_t iParent = -1; 310 int32_t iParent = -1;
301// int32_t iNode; 311// int32_t iNode;
302 312
@@ -352,6 +362,7 @@ void Bu::MyriadFs::unlink( const Bu::String &sPath )
352 362
353void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize ) 363void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize )
354{ 364{
365 Bu::MutexLocker lLock( mAccess );
355 int32_t iParent = -1; 366 int32_t iParent = -1;
356 int32_t iNode; 367 int32_t iNode;
357 iNode = lookupInode( sPath, iParent ); 368 iNode = lookupInode( sPath, iParent );
@@ -361,6 +372,7 @@ void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize )
361 372
362void Bu::MyriadFs::rename( const Bu::String &sFrom, const Bu::String &sTo ) 373void Bu::MyriadFs::rename( const Bu::String &sFrom, const Bu::String &sTo )
363{ 374{
375 Bu::MutexLocker lLock( mAccess );
364 mkHardLink( sFrom, sTo ); 376 mkHardLink( sFrom, sTo );
365 unlink( sFrom ); 377 unlink( sFrom );
366} 378}
@@ -572,27 +584,17 @@ int32_t Bu::MyriadFs::allocInode( uint16_t uPerms, uint32_t uSpecial )
572 { 584 {
573 case typeRegFile: 585 case typeRegFile:
574 case typeSymLink: 586 case typeSymLink:
575 { 587 rs.uStreamIndex = mStore.allocate();
576 Bu::MyriadStream ms = mStore.create(
577 Bu::Myriad::Create
578 );
579 rs.uStreamIndex = ms.getId();
580 }
581 break; 588 break;
582 589
583 case typeDir: 590 case typeDir:
584 {
585 Bu::MyriadStream ms = mStore.create(
586 Bu::Myriad::Create
587 );
588 rs.uStreamIndex = ms.getId();
589 }
590// sio << "Creating directory node, storage: " 591// sio << "Creating directory node, storage: "
591// << rs.uStreamIndex << sio.nl; 592// << rs.uStreamIndex << sio.nl;
592 { 593 {
593 Bu::MyriadStream msDir = mStore.open( 594 Bu::MyriadStream msDir = mStore.create(
594 rs.uStreamIndex, Bu::Myriad::Write 595 Bu::Myriad::Write
595 ); 596 );
597 rs.uStreamIndex = msDir.getId();
596 uint32_t uSize = 0; 598 uint32_t uSize = 0;
597 msDir.write( &uSize, 4 ); 599 msDir.write( &uSize, 4 );
598 } 600 }
diff --git a/src/unstable/myriadfs.h b/src/unstable/myriadfs.h
index ff14292..e3008bc 100644
--- a/src/unstable/myriadfs.h
+++ b/src/unstable/myriadfs.h
@@ -11,7 +11,7 @@
11#include <sys/types.h> 11#include <sys/types.h>
12 12
13#include "bu/myriad.h" 13#include "bu/myriad.h"
14#include "bu/readwritemutex.h" 14#include "bu/debugmutex.h"
15 15
16namespace Bu 16namespace Bu
17{ 17{
@@ -108,7 +108,7 @@ namespace Bu
108 Truncate = 0x08, ///< Truncate file if it does exist 108 Truncate = 0x08, ///< Truncate file if it does exist
109 Append = 0x10, ///< Always append on every write 109 Append = 0x10, ///< Always append on every write
110 NonBlock = 0x20, ///< Open file in non-blocking mode 110 NonBlock = 0x20, ///< Open file in non-blocking mode
111 Exclusive = 0x44, ///< Create file, if it exists then fail 111 Exclusive = 0x40, ///< Create file, if it exists then fail
112 112
113 // Helpful mixes 113 // Helpful mixes
114 ReadWrite = 0x03, ///< Open for reading and writing 114 ReadWrite = 0x03, ///< Open for reading and writing
@@ -172,7 +172,13 @@ namespace Bu
172 typedef Bu::Hash<int32_t, int32_t> NodeIndex; 172 typedef Bu::Hash<int32_t, int32_t> NodeIndex;
173 173
174 private: 174 private:
175 /**
176 * Lookup inode.
177 */
175 int32_t lookupInode( const Bu::String &sPath, int32_t &iParent ); 178 int32_t lookupInode( const Bu::String &sPath, int32_t &iParent );
179 /**
180 * Lookup inode.
181 */
176 int32_t lookupInode( Bu::String::const_iterator iStart, 182 int32_t lookupInode( Bu::String::const_iterator iStart,
177 int32_t iNode, int32_t &iParent ); 183 int32_t iNode, int32_t &iParent );
178 void readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ); 184 void readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs );
@@ -190,12 +196,12 @@ namespace Bu
190 void setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ); 196 void setTimes( int32_t iNode, int64_t iATime, int64_t iMTime );
191 void destroyNode( int32_t iNode ); 197 void destroyNode( int32_t iNode );
192 198
193 Bu::String filePart( const Bu::String &sPath ); 199 static Bu::String filePart( const Bu::String &sPath );
194 200
195 private: 201 private:
196 Bu::Stream &rStore; 202 Bu::Stream &rStore;
197 Bu::Myriad mStore; 203 Bu::Myriad mStore;
198 Bu::ReadWriteMutex mNodeIndex; 204 Bu::DebugMutex mAccess;
199 NodeIndex hNodeIndex; 205 NodeIndex hNodeIndex;
200 int32_t iUser; 206 int32_t iUser;
201 int32_t iGroup; 207 int32_t iGroup;