Listener (Str pool) : Thing (), poolname (pool) { page = 0; ParticipateInPool (poolname); INFORM ("Participating in pool '" + poolname + "'"); // Here we listen only for the exact descrip that we want ListenForDescrip ("image-request"); INFORM ("Listening for any proteins with descrip 'image-request'"); }
void Metabolize (const Protein &p) { INFORM (p); INFORM ("image-request protein received, responding..."); ImageData *tex = FetchImageData ("images/" + INT ((page++) % 6 + 1) + ".jpg"); if (tex) { Protein response = ProteinWithDescrip ("image-result"); AppendIngest (response, "image-texture", tex); Deposit (response, poolname); } else WARN ("Couldn't send response because we failed to load an image."); }
// _Defragment void BlockAllocator::Area::_Defragment() { D(SanityCheck()); //PRINT(("BlockAllocator::Area::_Defragment()\n")); // A trivial strategy for now: Keep the last free block and move the // others so that they can be joined with it. This is done iteratively // by moving the first free block to adjoin to the second one and // coalescing them. A free block is moved by moving the data blocks in // between. TFreeBlock *nextFree = NULL; while (fFirstFree && (nextFree = fFirstFree->GetNextFreeBlock()) != NULL) { Block *prevBlock = fFirstFree->GetPreviousBlock(); Block *nextBlock = fFirstFree->GetNextBlock(); size_t size = fFirstFree->GetSize(); // Used blocks are relatively position independed. We can move them // en bloc and only need to adjust the previous pointer of the first // one. if (!nextBlock->IsFree()) { // move the used blocks size_t chunkSize = (char*)nextFree - (char*)nextBlock; Block *nextFreePrev = nextFree->GetPreviousBlock(); Block *movedBlock = fFirstFree; memmove(movedBlock, nextBlock, chunkSize); movedBlock->SetPreviousBlock(prevBlock); // init the first free block Block *movedNextFreePrev = (Block*)((char*)nextFreePrev - size); fFirstFree = _MakeFreeBlock(movedBlock, chunkSize, movedNextFreePrev, size, true, NULL, nextFree); nextFree->SetPreviousFreeBlock(fFirstFree); // fix the references of the moved blocks for (Block *block = movedBlock; block != fFirstFree; block = block->GetNextBlock()) { block->FixReference(); } } else { // uncoalesced adjoining free block: That should never happen, // since we always coalesce as early as possible. INFORM(("Warning: Found uncoalesced adjoining free blocks!\n")); } // coalesce the first two blocks D(SanityCheck()); _CoalesceWithNext(fFirstFree); D(SanityCheck()); } //D(SanityCheck()); //PRINT(("BlockAllocator::Area::_Defragment() done\n")); }
// _InitNegativeEntries void Volume::_InitNegativeEntries() { // build a list of vnode IDs for (int32 i = 0; const char *entry = fSettings->HiddenEntryAt(i); i++) { if (entry && strlen(entry) > 0 && entry[0] != '/') { VNode node; if (FindEntry(fRootVNode, entry, &node) == B_OK && node.GetID() != fRootVNode->GetID()) { fNegativeEntries.AddItem(node.GetID()); } else INFORM(("WARNING: negative entry not found: `%s'\n", entry)); } } }
// _InitHashFunction void Volume::_InitHashFunction() { // get the hash function fHashFunction = hash_function_for_code(fSuperBlock->GetHashFunctionCode()); // try to detect it, if it is not set or is not the right one if (!fHashFunction || !_VerifyHashFunction(fHashFunction)) { INFORM(("No or wrong directory hash function. Try to detect...\n")); uint32 code = _DetectHashFunction(); fHashFunction = hash_function_for_code(code); // verify it if (fHashFunction) { if (_VerifyHashFunction(fHashFunction)) { INFORM(("Directory hash function successfully detected: %lu\n", code)); } else { fHashFunction = NULL; INFORM(("Detected directory hash function is not the right " "one.\n")); } } else INFORM(("Failed to detect the directory hash function.\n")); } }
// Init status_t Tree::Init(Volume *volume, Node *rootNode, uint32 treeHeight) { status_t error = (volume && volume->GetBlockCache() && rootNode ? B_OK : B_BAD_VALUE); if (error == B_OK) { if (treeHeight > kMaxTreeHeight) { // we don't need to fail, as we can deal with that gracefully INFORM(("WARNING: tree height greater maximal height: %lu\n", treeHeight)); } fVolume = volume; fBlockCache = fVolume->GetBlockCache(); fRootNode = rootNode; fRootNode->Get(); fTreeHeight = treeHeight; } return error; }
void FistVanish (PointingEvent *e) { StopHeeding (e); INFORM ("seismo FistVanish " + e -> Provenance ()); }
void FistAppear (PointingEvent *e) { INFORM ("seismo FistAppear " + e -> Provenance ()); if (IsHeedless ()) Heed (e); }
status_t Volume::Mount(const char* deviceName, uint32 flags) { // TODO: validate the FS in write mode as well! #if (B_HOST_IS_LENDIAN && defined(BFS_BIG_ENDIAN_ONLY)) \ || (B_HOST_IS_BENDIAN && defined(BFS_LITTLE_ENDIAN_ONLY)) // in big endian mode, we only mount read-only for now flags |= B_MOUNT_READ_ONLY; #endif DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0 ? O_RDONLY : O_RDWR); fDevice = opener.Device(); if (fDevice < B_OK) RETURN_ERROR(fDevice); if (opener.IsReadOnly()) fFlags |= VOLUME_READ_ONLY; // read the superblock if (Identify(fDevice, &fSuperBlock) != B_OK) { FATAL(("invalid superblock!\n")); return B_BAD_VALUE; } // initialize short hands to the superblock (to save byte swapping) fBlockSize = fSuperBlock.BlockSize(); fBlockShift = fSuperBlock.BlockShift(); fAllocationGroupShift = fSuperBlock.AllocationGroupShift(); // check if the device size is large enough to hold the file system off_t diskSize; if (opener.GetSize(&diskSize, &fDeviceBlockSize) != B_OK) RETURN_ERROR(B_ERROR); if (diskSize < (NumBlocks() << BlockShift())) RETURN_ERROR(B_BAD_VALUE); // set the current log pointers, so that journaling will work correctly fLogStart = fSuperBlock.LogStart(); fLogEnd = fSuperBlock.LogEnd(); if ((fBlockCache = opener.InitCache(NumBlocks(), fBlockSize)) == NULL) return B_ERROR; fJournal = new(std::nothrow) Journal(this); if (fJournal == NULL) return B_NO_MEMORY; status_t status = fJournal->InitCheck(); if (status < B_OK) { FATAL(("could not initialize journal: %s!\n", strerror(status))); return status; } // replaying the log is the first thing we will do on this disk status = fJournal->ReplayLog(); if (status != B_OK) { FATAL(("Replaying log failed, data may be corrupted, volume " "read-only.\n")); fFlags |= VOLUME_READ_ONLY; // TODO: if this is the boot volume, Bootscript will assume this // is a CD... // TODO: it would be nice to have a user visible alert instead // of letting him just find this in the syslog. } status = fBlockAllocator.Initialize(); if (status != B_OK) { FATAL(("could not initialize block bitmap allocator!\n")); return status; } fRootNode = new(std::nothrow) Inode(this, ToVnode(Root())); if (fRootNode != NULL && fRootNode->InitCheck() == B_OK) { status = publish_vnode(fVolume, ToVnode(Root()), (void*)fRootNode, &gBFSVnodeOps, fRootNode->Mode(), 0); if (status == B_OK) { // try to get indices root dir if (!Indices().IsZero()) { fIndicesNode = new(std::nothrow) Inode(this, ToVnode(Indices())); } if (fIndicesNode == NULL || fIndicesNode->InitCheck() < B_OK || !fIndicesNode->IsContainer()) { INFORM(("bfs: volume doesn't have indices!\n")); if (fIndicesNode) { // if this is the case, the index root node is gone bad, // and BFS switch to read-only mode fFlags |= VOLUME_READ_ONLY; delete fIndicesNode; fIndicesNode = NULL; } } else { // we don't use the vnode layer to access the indices node } } else { FATAL(("could not create root node: publish_vnode() failed!\n")); delete fRootNode; return status; } } else { status = B_BAD_VALUE; FATAL(("could not create root node!\n")); return status; } // all went fine opener.Keep(); return B_OK; }