Removed the remnants of the dispatcher mechanism.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29390 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-03-03 23:42:20 +00:00
parent 608990b488
commit fac733d2f6
17 changed files with 48 additions and 938 deletions

View File

@ -1,33 +0,0 @@
// DispatcherDefs.h
#ifndef USERLAND_FS_DISPATCHER_DEFS_H
#define USERLAND_FS_DISPATCHER_DEFS_H
#include "FSCapabilities.h"
#include "Port.h"
namespace UserlandFSUtil {
extern const char* kUserlandFSDispatcherPortName;
extern const char* kUserlandFSDispatcherReplyPortName;
struct fs_init_info {
FSCapabilities capabilities;
client_fs_type clientFSType;
int32 portInfoCount;
Port::Info portInfos[0];
};
} // namespace UserlandFSUtil
using UserlandFSUtil::kUserlandFSDispatcherPortName;
using UserlandFSUtil::kUserlandFSDispatcherReplyPortName;
using UserlandFSUtil::fs_init_info;
enum {
UFS_DISPATCHER_CONNECT = 'cnct',
UFS_DISPATCHER_CONNECT_ACK = 'cack',
};
#endif // USERLAND_FS_DISPATCHER_DEFS_H

View File

@ -1,5 +1,7 @@
// FSCapabilities.h
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_FS_CAPABILITIES_H
#define USERLAND_FS_FS_CAPABILITIES_H

View File

@ -0,0 +1,25 @@
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_USERLAND_FS_DEFS_H
#define USERLAND_FS_USERLAND_FS_DEFS_H
#include "FSCapabilities.h"
#include "Port.h"
namespace UserlandFSUtil {
struct fs_init_info {
FSCapabilities capabilities;
client_fs_type clientFSType;
int32 portInfoCount;
Port::Info portInfos[0];
};
} // namespace UserlandFSUtil
using UserlandFSUtil::fs_init_info;
#endif // USERLAND_FS_USERLAND_FS_DEFS_H

View File

@ -15,12 +15,12 @@
#include "AutoDeleter.h"
#include "DispatcherDefs.h"
#include "FileSystem.h"
#include "RequestAllocator.h"
#include "RequestPort.h"
#include "Requests.h"
#include "SingleReplyRequestHandler.h"
#include "UserlandFSDefs.h"
// constructor

View File

@ -16,7 +16,6 @@ DEFINES += DEBUG_APP="\\\"userlandfs\\\"" ;
KernelAddon userlandfs
: AreaSupport.cpp
Debug.cpp
DispatcherDefs.cpp
LazyInitializable.cpp
Locker.cpp
ObjectTracker.cpp

View File

@ -9,12 +9,12 @@
#include "Compatibility.h"
#include "Debug.h"
#include "DispatcherDefs.h"
#include "FileSystem.h"
#include "FileSystemInitializer.h"
#include "KernelDebug.h"
#include "RequestPort.h"
#include "Requests.h"
#include "UserlandFSDefs.h"
UserlandFS* UserlandFS::sUserlandFS = NULL;

View File

@ -1,10 +0,0 @@
// DispatcherDefs.cpp
#include "DispatcherDefs.h"
namespace UserlandFSUtil {
const char* kUserlandFSDispatcherPortName = "userland fs dispatcher";
const char* kUserlandFSDispatcherReplyPortName = "userland fs dispatcher reply";
}

View File

@ -1,146 +0,0 @@
// FileSystem.cpp
#include "DispatcherFileSystem.h"
#include <Application.h>
#include <Autolock.h>
#include <Entry.h>
#include <Message.h>
#include <Messenger.h>
#include <Roster.h>
#include "Debug.h"
#include "DispatcherDefs.h"
#include "ServerDefs.h"
// constructor
FileSystem::FileSystem(const char* name, status_t* _error)
: LazyInitializable(),
Referencable(),
fName(),
fInfo(NULL),
fTeam(-1),
fFinishInitSemaphore(-1),
fTeamLock()
{
status_t error = B_OK;
if (!fName.SetTo(name))
error = B_NO_MEMORY;
if (_error)
*_error = error;
}
// constructor
FileSystem::FileSystem(team_id team, FSInfo* info, status_t* _error)
: LazyInitializable(false),
Referencable(),
fName(),
fInfo(info),
fTeam(team),
fFinishInitSemaphore(-1),
fTeamLock()
{
status_t error = B_OK;
if (!fName.SetTo(info->GetName()))
error = B_NO_MEMORY;
if (_error)
*_error = error;
}
// destructor
FileSystem::~FileSystem()
{
if (fFinishInitSemaphore >= 0)
delete_sem(fFinishInitSemaphore);
delete fInfo;
}
// GetName
const char*
FileSystem::GetName() const
{
return fName.GetString();
}
// GetInfo
const FSInfo*
FileSystem::GetInfo() const
{
return fInfo;
}
// GetTeam
team_id
FileSystem::GetTeam() const
{
BAutolock _(fTeamLock);
return fTeam;
}
// CompleteInit
void
FileSystem::CompleteInit(FSInfo* info)
{
fInfo = info;
if (fFinishInitSemaphore >= 0)
release_sem(fFinishInitSemaphore);
}
// AbortInit
void
FileSystem::AbortInit()
{
if (fInitStatus == B_OK)
fInitStatus = B_NO_INIT;
if (fFinishInitSemaphore >= 0)
release_sem(fFinishInitSemaphore);
}
// FirstTimeInit
status_t
FileSystem::FirstTimeInit()
{
if (fName.GetLength() == 0)
RETURN_ERROR(B_BAD_VALUE);
// create the init finish semaphore
fFinishInitSemaphore = create_sem(0, "FS init finish sem");
if (fFinishInitSemaphore < 0)
return fFinishInitSemaphore;
// get a server entry ref
app_info appInfo;
status_t error = be_app->GetAppInfo(&appInfo);
if (error != B_OK)
RETURN_ERROR(error);
// launch a server instance
team_id team = -1;
fTeamLock.Lock();
if (gServerSettings.ShallEnterDebugger()) {
int argc = 2;
const char *argv[] = { "--debug", fName.GetString(), NULL };
error = be_roster->Launch(&appInfo.ref, argc, argv, &team);
} else {
int argc = 1;
const char *argv[] = { fName.GetString(), NULL };
error = be_roster->Launch(&appInfo.ref, argc, argv, &team);
}
fTeam = team;
fTeamLock.Unlock();
if (error != B_OK)
RETURN_ERROR(error);
// wait for the initialization to complete/fail
error = _WaitForInitToFinish();
RETURN_ERROR(error);
}
// _WaitForInitToFinish
status_t
FileSystem::_WaitForInitToFinish()
{
status_t error = acquire_sem(fFinishInitSemaphore);
delete_sem(fFinishInitSemaphore);
fFinishInitSemaphore = -1;
if (error != B_OK)
return error;
return (fInfo ? B_OK : B_ERROR);
}

View File

@ -1,48 +0,0 @@
// FileSystem.h
#ifndef USERLAND_FS_DISPATCHER_FILE_SYSTEM_H
#define USERLAND_FS_DISPATCHER_FILE_SYSTEM_H
#include <Locker.h>
#include "FSInfo.h"
#include "LazyInitializable.h"
#include "Referencable.h"
#include "String.h"
namespace UserlandFS {
namespace Dispatcher {
class FileSystem : public LazyInitializable, public Referencable {
public:
FileSystem(const char* name, status_t* error);
FileSystem(team_id team, FSInfo* info,
status_t* error);
~FileSystem();
const char* GetName() const;
const FSInfo* GetInfo() const;
team_id GetTeam() const;
void CompleteInit(FSInfo* info);
void AbortInit();
private:
virtual status_t FirstTimeInit();
status_t _WaitForInitToFinish();
private:
String fName;
FSInfo* fInfo;
team_id fTeam;
sem_id fFinishInitSemaphore;
mutable BLocker fTeamLock;
};
} // namespace Dispatcher
} // namespace UserlandFS
using UserlandFS::Dispatcher::FileSystem;
#endif // USERLAND_FS_DISPATCHER_FILE_SYSTEM_H

View File

@ -1,182 +0,0 @@
// FSInfo.h
#ifndef USERLAND_FS_FS_INFO_H
#define USERLAND_FS_FS_INFO_H
#include <new>
#include <string.h>
#include <Message.h>
#include "FSCapabilities.h"
#include "Port.h"
#include "String.h"
using std::nothrow;
namespace UserlandFS {
// FSInfo
class FSInfo {
public:
FSInfo()
: fInfos(NULL),
fCount(0)
{
}
FSInfo(const char* fsName, const Port::Info* infos, int32 count,
const FSCapabilities& capabilities, client_fs_type clientFSType)
: fName(),
fInfos(NULL),
fCount(0)
{
SetTo(fsName, infos, count, capabilities, clientFSType);
}
FSInfo(const BMessage* message)
: fName(),
fInfos(NULL),
fCount(0)
{
SetTo(message);
}
FSInfo(const FSInfo& other)
: fName(),
fInfos(NULL),
fCount(0)
{
SetTo(other.GetName(), other.fInfos, other.fCount, other.fCapabilities,
other.fClientFSType);
}
~FSInfo()
{
Unset();
}
status_t SetTo(const char* fsName, const Port::Info* infos, int32 count,
const FSCapabilities& capabilities, client_fs_type clientFSType)
{
Unset();
if (!fsName || !infos || count <= 0)
return B_BAD_VALUE;
if (!fName.SetTo(fsName))
return B_NO_MEMORY;
fInfos = new(nothrow) Port::Info[count];
if (!fInfos)
return B_NO_MEMORY;
memcpy(fInfos, infos, sizeof(Port::Info) * count);
fCapabilities = capabilities;
fClientFSType = clientFSType;
fCount = count;
return B_OK;
}
status_t SetTo(const BMessage* message)
{
Unset();
if (!message)
return B_BAD_VALUE;
const void* infos;
ssize_t size;
const char* fsName;
const void* capabilities;
ssize_t capabilitiesSize;
int32 clientFSType;
if (message->FindData("infos", B_RAW_TYPE, &infos, &size) != B_OK
|| size < 0 || message->FindString("fsName", &fsName) != B_OK
|| message->FindData("capabilities", B_RAW_TYPE, &capabilities,
&capabilitiesSize) != B_OK
|| capabilitiesSize != sizeof(FSCapabilities)
|| message->FindInt32("clientFSType", &clientFSType) != B_OK) {
return B_BAD_VALUE;
}
return SetTo(fsName, (const Port::Info*)infos,
size / sizeof(Port::Info), *(const FSCapabilities*)capabilities,
(client_fs_type)clientFSType);
}
void Unset()
{
fName.Unset();
delete[] fInfos;
fInfos = NULL;
fCount = 0;
}
const char* GetName() const
{
return fName.GetString();
}
Port::Info* GetInfos() const
{
return fInfos;
}
int32 CountInfos() const
{
return fCount;
}
int32 GetInfosSize() const
{
return fCount * sizeof(Port::Info);
}
const FSCapabilities& GetCapabilities() const
{
return fCapabilities;
}
client_fs_type GetClientFSType() const
{
return fClientFSType;
}
status_t Archive(BMessage* archive)
{
if (!fName.GetString() || !fInfos)
return B_NO_INIT;
status_t error = archive->AddString("fsName", fName.GetString());
if (error != B_OK)
return error;
error = archive->AddData("infos", B_RAW_TYPE, fInfos,
fCount * sizeof(Port::Info));
if (error != B_OK)
return error;
error = archive->AddData("capabilities", B_RAW_TYPE, &fCapabilities,
sizeof(FSCapabilities));
if (error != B_OK)
return error;
return archive->AddInt32("clientFSType", fClientFSType);
}
private:
String fName;
Port::Info* fInfos;
int32 fCount;
FSCapabilities fCapabilities;
client_fs_type fClientFSType;
};
} // namespace UserlandFS
using UserlandFS::FSInfo;
#endif // USERLAND_FS_FS_INFO_H

View File

@ -20,7 +20,6 @@ Application userlandfs_server
:
AreaSupport.cpp
Debug.cpp
DispatcherDefs.cpp
driver_settings.c
LazyInitializable.cpp
Locker.cpp
@ -35,13 +34,11 @@ Application userlandfs_server
SingleReplyRequestHandler.cpp
String.cpp
DispatcherFileSystem.cpp
FileSystem.cpp
kernel_emu.cpp
main.cpp
RequestThread.cpp
ServerDefs.cpp
# UserlandFSDispatcher.cpp
UserlandFSServer.cpp
UserlandRequestHandler.cpp
Volume.cpp

View File

@ -1,4 +1,7 @@
// ServerDefs.cpp
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "ServerDefs.h"
@ -29,7 +32,3 @@ ServerSettings::ShallEnterDebugger() const
// the global settings
ServerSettings UserlandFS::gServerSettings;
const char* UserlandFS::kUserlandFSDispatcherClipboardName
= "userland fs dispatcher";

View File

@ -1,5 +1,7 @@
// ServerDefs.h
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_SERVER_DEFS_H
#define USERLAND_FS_SERVER_DEFS_H
@ -21,21 +23,12 @@ private:
extern ServerSettings gServerSettings;
enum {
UFS_REGISTER_FS = 'rgfs',
UFS_REGISTER_FS_ACK = 'rfsa',
UFS_REGISTER_FS_DENIED = 'rfsd',
};
extern const char* kUserlandFSDispatcherClipboardName;
static const int32 kRequestPortSize = B_PAGE_SIZE;
} // namespace UserlandFS
using UserlandFS::ServerSettings;
using UserlandFS::gServerSettings;
using UserlandFS::kUserlandFSDispatcherClipboardName;
using UserlandFS::kRequestPortSize;
#endif // USERLAND_FS_SERVER_DEFS_H

View File

@ -1,422 +0,0 @@
// UserlandFSDispatcher.cpp
#include <new>
#include <Application.h>
#include <Clipboard.h>
#include <Locker.h>
#include <Message.h>
#include <Roster.h>
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "Compatibility.h"
#include "Debug.h"
#include "DispatcherDefs.h"
#include "DispatcherFileSystem.h"
#include "FSInfo.h"
#include "RequestAllocator.h"
#include "RequestPort.h"
#include "Requests.h"
#include "ServerDefs.h"
#include "String.h"
#include "UserlandFSDispatcher.h"
// constructor
UserlandFSDispatcher::UserlandFSDispatcher(const char* signature)
: BApplication(signature),
fTerminating(false),
fRequestProcessor(-1),
fConnectionPort(-1),
fConnectionReplyPort(-1),
fRequestLock(),
fRequestPort(NULL)
{
}
// destructor
UserlandFSDispatcher::~UserlandFSDispatcher()
{
fTerminating = true;
// stop roster watching
be_roster->StopWatching(this);
// close/delete the ports
fRequestLock.Lock();
if (fRequestPort)
fRequestPort->Close();
fRequestLock.Unlock();
if (fConnectionPort >= 0)
delete_port(fConnectionPort);
if (fConnectionReplyPort >= 0)
delete_port(fConnectionReplyPort);
// wait for the request processor
if (fRequestProcessor >= 0) {
int32 result;
wait_for_thread(fRequestProcessor, &result);
}
}
// Init
status_t
UserlandFSDispatcher::Init()
{
// ensure that we are the only dispatcher
BClipboard clipboard(kUserlandFSDispatcherClipboardName);
if (!clipboard.Lock()) {
ERROR(("Failed to lock the clipboard.\n"));
return B_ERROR;
}
status_t error = B_OK;
if (BMessage* data = clipboard.Data()) {
// check the old value in the clipboard
BMessenger messenger;
if (data->FindMessenger("messenger", &messenger) == B_OK) {
if (messenger.IsValid()) {
PRINT(("There's already a dispatcher running.\n"));
error = B_ERROR;
}
}
// clear the clipboard
if (error == B_OK) {
clipboard.Clear();
data = clipboard.Data();
if (!data)
error = B_ERROR;
}
// add our messenger
if (error == B_OK) {
SET_ERROR(error, data->AddMessenger("messenger", be_app_messenger));
if (error == B_OK)
SET_ERROR(error, clipboard.Commit());
// work-around for BeOS R5: The very first commit to a clipboard
// (i.e. the one that creates the clipboard) seems to be ignored.
if (error == B_OK)
SET_ERROR(error, clipboard.Commit());
if (error != B_OK)
ERROR(("Failed to set clipboard messenger.\n"));
}
} else {
ERROR(("Failed to get clipboard data container\n"));
error = B_ERROR;
}
clipboard.Unlock();
if (error != B_OK)
return error;
// create the connection port and connection reply port
fConnectionPort = create_port(1, kUserlandFSDispatcherPortName);
if (fConnectionPort < 0)
return fConnectionPort;
fConnectionReplyPort = create_port(1, kUserlandFSDispatcherReplyPortName);
if (fConnectionReplyPort < 0)
return fConnectionReplyPort;
// start watching for terminated applications
error = be_roster->StartWatching(this, B_REQUEST_QUIT);
if (error != B_OK)
return error ;
// spawn request processor thread
fRequestProcessor = spawn_thread(_RequestProcessorEntry,
"main request processor", B_NORMAL_PRIORITY, this);
if (fRequestProcessor < 0)
return fRequestProcessor;
resume_thread(fRequestProcessor);
return B_OK;
}
// MessageReceived
void
UserlandFSDispatcher::MessageReceived(BMessage* message)
{
switch (message->what) {
case UFS_REGISTER_FS:
{
// get the team
team_id team;
status_t error = message->FindInt32("team", &team);
if (error != B_OK)
PRINT(("UFS_REGISTER_FS failed: no team\n"));
// get the FS info
FSInfo* info = NULL;
if (error == B_OK) {
info = new(nothrow) FSInfo;
if (info) {
error = info->SetTo(message);
} else {
error = B_NO_MEMORY;
PRINT(("UFS_REGISTER_FS failed: failed to allocate "
"FSInfo\n"));
}
}
ObjectDeleter<FSInfo> infoDeleter(info);
// find the FileSystem
FileSystem* fileSystem = NULL;
if (error == B_OK) {
AutoLocker<FileSystemMap> _(fFileSystems);
fileSystem = _GetFileSystemNoInit(team);
if (fileSystem) {
fileSystem->CompleteInit(info);
infoDeleter.Detach();
} else {
PRINT(("UFS_REGISTER_FS: no FileSystem found for "
"team %ld, trying to register anyway\n", team));
// try to find by name
fileSystem = fFileSystems.Get(info->GetName());
if (fileSystem) {
// there's already an FS with that name registered
PRINT(("UFS_REGISTER_FS failed: FileSystem with "
"name %s does already exist.\n", info->GetName()));
fileSystem = NULL;
error = B_ERROR;
} else {
// the FS is not known yet: create one
fileSystem = new FileSystem(team, info, &error);
if (fileSystem) {
infoDeleter.Detach();
} else {
error = B_NO_MEMORY;
PRINT(("UFS_REGISTER_FS failed: failed to allocate "
"FileSystem\n"));
}
// add it
if (error == B_OK) {
error = fFileSystems.Put(info->GetName(),
fileSystem);
if (error != B_OK) {
PRINT(("UFS_REGISTER_FS failed: failed to "
"add FileSystem\n"));
delete fileSystem;
}
}
}
}
}
// send the reply
if (error == B_OK)
message->SendReply(UFS_REGISTER_FS_ACK);
else
message->SendReply(UFS_REGISTER_FS_DENIED);
if (fileSystem)
_PutFileSystem(fileSystem);
break;
}
case B_SOME_APP_QUIT:
{
// get the team
team_id team;
status_t error = message->FindInt32("be:team", &team);
if (error != B_OK)
return;
// find the FileSystem
FileSystem* fileSystem = _GetFileSystemNoInit(team);
if (!fileSystem)
return;
// abort the initialization
fileSystem->AbortInit();
_PutFileSystem(fileSystem);
}
default:
BApplication::MessageReceived(message);
}
}
// _GetFileSystem
status_t
UserlandFSDispatcher::_GetFileSystem(const char* name, FileSystem** _fileSystem)
{
if (!name || !_fileSystem)
RETURN_ERROR(B_BAD_VALUE);
// get the file system
FileSystem* fileSystem;
{
AutoLocker<FileSystemMap> _(fFileSystems);
fileSystem = fFileSystems.Get(name);
if (fileSystem) {
fileSystem->AddReference();
} else {
// doesn't exists yet: create
status_t error;
fileSystem = new(nothrow) FileSystem(name, &error);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
if (error == B_OK)
error = fFileSystems.Put(fileSystem->GetName(), fileSystem);
if (error != B_OK) {
delete fileSystem;
RETURN_ERROR(error);
}
}
}
// prepare access
status_t error = fileSystem->Access();
if (error != B_OK) {
_PutFileSystem(fileSystem);
RETURN_ERROR(error);
}
*_fileSystem = fileSystem;
return B_OK;
}
// _GetFileSystemNoInit
FileSystem*
UserlandFSDispatcher::_GetFileSystemNoInit(team_id team)
{
AutoLocker<FileSystemMap> _(fFileSystems);
for (FileSystemMap::Iterator it = fFileSystems.GetIterator();
it.HasNext();) {
FileSystem* fileSystem = it.Next().value;
if (fileSystem->GetTeam() == team) {
// found it
if (fileSystem)
fileSystem->AddReference();
return fileSystem;
}
}
return NULL;
}
// _PutFileSystem
status_t
UserlandFSDispatcher::_PutFileSystem(FileSystem* fileSystem)
{
if (!fileSystem)
RETURN_ERROR(B_BAD_VALUE);
AutoLocker<FileSystemMap> _(fFileSystems);
if (fFileSystems.Get(fileSystem->GetName()) != fileSystem)
RETURN_ERROR(B_BAD_VALUE);
if (fileSystem->RemoveReference() && fileSystem->InitCheck() != B_OK) {
PRINT(("removing FileSystem `%s'\n", fileSystem->GetName()));
fFileSystems.Remove(fileSystem->GetName());
delete fileSystem;
}
return B_OK;
}
// _WaitForConnection
bool
UserlandFSDispatcher::_WaitForConnection()
{
while (!fTerminating) {
int32 code;
char buffer;
size_t bytesRead = read_port(fConnectionPort, &code, &buffer, 0);
if (bytesRead >= 0 && code == UFS_DISPATCHER_CONNECT) {
const Port::Info* info = fRequestPort->GetPortInfo();
size_t bytesWritten = write_port(fConnectionReplyPort,
UFS_DISPATCHER_CONNECT_ACK, info, sizeof(Port::Info));
if (bytesWritten >= 0)
return true;
}
}
return false;
}
// _ProcessRequests
status_t
UserlandFSDispatcher::_ProcessRequests()
{
while (!fTerminating) {
Request* request;
status_t error = fRequestPort->ReceiveRequest(&request);
if (error != B_OK)
RETURN_ERROR(error);
RequestReleaser _(fRequestPort, request);
// check the request type
if (request->GetType() == UFS_DISCONNECT_REQUEST)
return B_OK;
if (request->GetType() != FS_CONNECT_REQUEST)
RETURN_ERROR(B_BAD_VALUE);
PRINT(("UserlandFSDispatcher::_ProcessRequests(): received FS connect "
"request\n"));
// it's an FS connect request
FSConnectRequest* connectRequest = (FSConnectRequest*)request;
// get the FS name
int32 len = connectRequest->fsName.GetSize();
status_t result = B_OK;
if (len <= 0)
result = B_BAD_DATA;
String fsName;
if (result == B_OK)
fsName.SetTo((const char*)connectRequest->fsName.GetData(), len);
if (result == B_OK && fsName.GetLength() == 0)
result = B_BAD_DATA;
// prepare the reply
RequestAllocator allocator(fRequestPort->GetPort());
FSConnectReply* reply;
error = AllocateRequest(allocator, &reply);
if (error != B_OK)
RETURN_ERROR(error);
FileSystem* fileSystem = NULL;
if (result == B_OK)
result = _GetFileSystem(fsName.GetString(), &fileSystem);
if (result == B_OK) {
const FSInfo* info = fileSystem->GetInfo();
result = allocator.AllocateData(reply->portInfos,
info->GetInfos(), info->GetInfosSize(), sizeof(Port::Info));
reply->portInfoCount = info->CountInfos();
reply->capabilities = info->GetCapabilities();
reply->clientFSType = info->GetClientFSType();
_PutFileSystem(fileSystem);
}
reply->error = result;
// send it
error = fRequestPort->SendRequest(&allocator);
if (error != B_OK)
RETURN_ERROR(error);
}
return B_OK;
}
// _RequestProcessorEntry
int32
UserlandFSDispatcher::_RequestProcessorEntry(void* data)
{
return ((UserlandFSDispatcher*)data)->_RequestProcessor();
}
// _RequestProcessor
int32
UserlandFSDispatcher::_RequestProcessor()
{
PRINT(("UserlandFSDispatcher::_RequestProcessor()\n"));
while (!fTerminating) {
// allocate a request port
status_t error = B_OK;
{
fRequestLock.Lock();
fRequestPort = new(nothrow) RequestPort(kRequestPortSize);
if (fRequestPort)
error = fRequestPort->InitCheck();
else
error = B_NO_MEMORY;
if (error != B_OK) {
delete fRequestPort;
fRequestPort = NULL;
}
fRequestLock.Unlock();
}
if (error != B_OK) {
be_app->PostMessage(B_QUIT_REQUESTED);
PRINT((" failed to allocate request port: %s\n", strerror(error)));
return error;
}
// wait for a connection and process the requests
if (_WaitForConnection()) {
PRINT(("UserlandFSDispatcher::_RequestProcessor(): connected\n"));
_ProcessRequests();
PRINT(("UserlandFSDispatcher::_RequestProcessor(): "
"disconnected\n"));
}
// delete the request port
fRequestLock.Lock();
delete fRequestPort;
fRequestPort = NULL;
fRequestLock.Unlock();
}
PRINT(("UserlandFSDispatcher::_RequestProcessor() done\n"));
return B_OK;
}

View File

@ -1,68 +0,0 @@
// UserlandFSDispatcher.h
#ifndef USERLAND_FS_DISPATCHER_H
#define USERLAND_FS_DISPATCHER_H
#include <Application.h>
#include <Locker.h>
#include <OS.h>
#include "HashMap.h"
namespace UserlandFSUtil {
class RequestPort;
class String;
}
using UserlandFSUtil::RequestPort;
using UserlandFSUtil::String;
namespace UserlandFS {
namespace Dispatcher {
class FileSystem;
}
using Dispatcher::FileSystem;
class UserlandFSDispatcher : public BApplication {
public:
UserlandFSDispatcher(const char* signature);
virtual ~UserlandFSDispatcher();
status_t Init();
virtual void MessageReceived(BMessage* message);
private:
status_t _GetFileSystem(const char* name,
FileSystem** fileSystem);
status_t _GetFileSystemNoInit(const char* name,
FileSystem** fileSystem);
FileSystem* _GetFileSystemNoInit(team_id team);
status_t _PutFileSystem(FileSystem* fileSystem);
bool _WaitForConnection();
status_t _ProcessRequests();
static int32 _RequestProcessorEntry(void* data);
int32 _RequestProcessor();
private:
typedef SynchronizedHashMap<String, FileSystem*> FileSystemMap;
bool fTerminating;
thread_id fRequestProcessor;
port_id fConnectionPort;
port_id fConnectionReplyPort;
BLocker fRequestLock;
RequestPort* fRequestPort;
FileSystemMap fFileSystems;
};
} // namespace UserlandFS
using UserlandFS::UserlandFSDispatcher;
#endif // USERLAND_FS_DISPATCHER_H

View File

@ -1,4 +1,7 @@
// UserlandFSServer.cpp
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "UserlandFSServer.h"
@ -19,11 +22,10 @@
#include "AutoLocker.h"
#include "Compatibility.h"
#include "Debug.h"
#include "DispatcherDefs.h"
#include "FileSystem.h"
#include "FSInfo.h"
#include "RequestThread.h"
#include "ServerDefs.h"
#include "UserlandFSDefs.h"
static const int32 kRequestThreadCount = 10;

View File

@ -1,5 +1,7 @@
// UserlandFSServer.h
/*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_SERVER_H
#define USERLAND_FS_SERVER_H