Stripped down the fake_app_server a bit more, so that breaking the build
while working on the app_server should less likely happen - hopefully. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16836 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
99d94ad2e0
commit
bd3c41fe37
@ -24,6 +24,10 @@
|
||||
// Description: main manager object for the app_server
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
#include "AppServer.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerProtocol.h"
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include <AppDefs.h>
|
||||
#include <Directory.h>
|
||||
@ -34,29 +38,19 @@
|
||||
#include <PortLink.h>
|
||||
#include <StopWatch.h>
|
||||
|
||||
#include "BitmapManager.h"
|
||||
#include "ColorSet.h"
|
||||
#include "RegistrarDefs.h"
|
||||
#include "RGBColor.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerCursor.h"
|
||||
#include "ServerProtocol.h"
|
||||
#include "SystemPalette.h"
|
||||
|
||||
#include "AppServer.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//#define DEBUG_KEYHANDLING
|
||||
//#define DEBUG_SERVER
|
||||
|
||||
#ifdef DEBUG_KEYHANDLING
|
||||
# include <stdio.h>
|
||||
# define KBTRACE(x) printf x
|
||||
#else
|
||||
# define KBTRACE(x) ;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERVER
|
||||
# include <stdio.h>
|
||||
# define STRACE(x) printf x
|
||||
#else
|
||||
# define STRACE(x) ;
|
||||
@ -92,7 +86,6 @@ AppServer::AppServer(void)
|
||||
|
||||
fAppList = new BList();
|
||||
fQuittingServer = false;
|
||||
make_decorator = NULL;
|
||||
|
||||
// We need this in order for new_decorator to be able to instantiate new decorators
|
||||
sAppServer = this;
|
||||
@ -103,19 +96,10 @@ AppServer::AppServer(void)
|
||||
// This locker is for app_server and Picasso to vy for control of the ServerApp list
|
||||
fAppListLock = create_sem(1,"app_server_applist_sem");
|
||||
|
||||
// This locker is to mediate access to the make_decorator pointer
|
||||
fDecoratorLock = create_sem(1,"app_server_decor_sem");
|
||||
|
||||
// Spawn our thread-monitoring thread
|
||||
fPicassoThreadID = spawn_thread(PicassoThread, "picasso", B_NORMAL_PRIORITY, this);
|
||||
if (fPicassoThreadID >= 0)
|
||||
resume_thread(fPicassoThreadID);
|
||||
|
||||
fDecoratorName ="Default";
|
||||
|
||||
#if 0
|
||||
LaunchCursorThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -124,39 +108,11 @@ AppServer::AppServer(void)
|
||||
Reached only when the server is asked to shut down in Test mode. Kills all apps, shuts down the
|
||||
desktop, kills the housekeeping threads, etc.
|
||||
*/
|
||||
AppServer::~AppServer(void)
|
||||
AppServer::~AppServer()
|
||||
{
|
||||
debugger("We shouldn't be here! MainLoop()::B_QUIT_REQUESTED should see if we can exit the server.\n");
|
||||
/*
|
||||
ServerApp *tempapp;
|
||||
int32 i;
|
||||
acquire_sem(fAppListLock);
|
||||
for(i=0;i<fAppList->CountItems();i++)
|
||||
{
|
||||
tempapp=(ServerApp *)fAppList->ItemAt(i);
|
||||
if(tempapp!=NULL)
|
||||
delete tempapp;
|
||||
}
|
||||
delete fAppList;
|
||||
release_sem(fAppListLock);
|
||||
|
||||
delete bitmapmanager;
|
||||
|
||||
delete gDesktop;
|
||||
|
||||
// If these threads are still running, kill them - after this, if exit_poller
|
||||
// is deleted, who knows what will happen... These things will just return an
|
||||
// error and fail if the threads have already exited.
|
||||
kill_thread(fPicassoThreadID);
|
||||
kill_thread(fCursorThreadID);
|
||||
kill_thread(fISThreadID);
|
||||
|
||||
delete fontserver;
|
||||
|
||||
make_decorator=NULL;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Thread function for watching for dead apps
|
||||
\param data Pointer to the app_server to which the thread belongs
|
||||
@ -246,92 +202,6 @@ AppServer::MainLoop(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Loads the specified decorator and sets the system's decorator to it.
|
||||
\param path Path to the decorator to load
|
||||
\return True if successful, false if not.
|
||||
|
||||
If the server cannot load the specified decorator, nothing changes. Passing a
|
||||
NULL string to this function sets the decorator to the internal one.
|
||||
*/
|
||||
bool
|
||||
AppServer::LoadDecorator(const char *path)
|
||||
{
|
||||
// Loads a window decorator based on the supplied path and forces a decorator update.
|
||||
// If it cannot load the specified decorator, it will retain the current one and
|
||||
// return false. Note that passing a NULL string to this function sets the decorator
|
||||
// to the internal one.
|
||||
|
||||
// passing the string "Default" will set the window decorator to the app_server's
|
||||
// internal one
|
||||
if(!path)
|
||||
{
|
||||
make_decorator= NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
create_decorator *pcreatefunc= NULL;
|
||||
status_t stat;
|
||||
image_id addon;
|
||||
|
||||
addon = load_add_on(path);
|
||||
if (addon < B_OK)
|
||||
return false;
|
||||
|
||||
// As of now, we do nothing with decorator versions, but the possibility exists
|
||||
// that the API will change even though I cannot forsee any reason to do so. If
|
||||
// we *did* do anything with decorator versions, the assignment to a global would
|
||||
// go here.
|
||||
|
||||
// Get the instantiation function
|
||||
stat = get_image_symbol(addon, "instantiate_decorator",
|
||||
B_SYMBOL_TYPE_TEXT, (void**)&pcreatefunc);
|
||||
if (stat != B_OK) {
|
||||
unload_add_on(addon);
|
||||
return false;
|
||||
}
|
||||
|
||||
BPath temppath(path);
|
||||
fDecoratorName=temppath.Leaf();
|
||||
|
||||
acquire_sem(fDecoratorLock);
|
||||
make_decorator=pcreatefunc;
|
||||
fDecoratorID=addon;
|
||||
release_sem(fDecoratorLock);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Loads decorator settings on disk or the default if settings are invalid
|
||||
void
|
||||
AppServer::InitDecorators(void)
|
||||
{
|
||||
BMessage settings;
|
||||
|
||||
BDirectory dir;
|
||||
if (dir.SetTo(SERVER_SETTINGS_DIR) == B_ENTRY_NOT_FOUND)
|
||||
create_directory(SERVER_SETTINGS_DIR, 0777);
|
||||
|
||||
BString path(SERVER_SETTINGS_DIR);
|
||||
path += "DecoratorSettings";
|
||||
BFile file(path.String(), B_READ_ONLY);
|
||||
|
||||
if (file.InitCheck() == B_OK
|
||||
&& settings.Unflatten(&file) == B_OK) {
|
||||
BString itemtext;
|
||||
if (settings.FindString("decorator", &itemtext) == B_OK) {
|
||||
path.SetTo(DECORATORS_DIR);
|
||||
path += itemtext;
|
||||
if (LoadDecorator(path.String()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We got this far, so something must have gone wrong. We set make_decorator
|
||||
// to NULL so that the decorator allocation routine knows to utilize the included
|
||||
// default decorator instead of an addon.
|
||||
make_decorator = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Message handling function for all messages sent to the app_server
|
||||
\param code ID of the message sent
|
||||
@ -533,7 +403,6 @@ main(int argc, char** argv)
|
||||
if (find_port(SERVER_PORT_NAME) >= B_OK)
|
||||
return -1;
|
||||
|
||||
srand(real_time_clock_usecs());
|
||||
AppServer app_server;
|
||||
app_server.Run();
|
||||
return 0;
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <Application.h>
|
||||
#include <Window.h>
|
||||
#include <String.h>
|
||||
#include "Decorator.h"
|
||||
|
||||
#include "ServerConfig.h"
|
||||
|
||||
class Layer;
|
||||
@ -58,19 +58,9 @@ private:
|
||||
void LaunchCursorThread();
|
||||
void LaunchInputServer();
|
||||
|
||||
friend Decorator* new_decorator(BRect rect, const char *title,
|
||||
int32 wlook, int32 wfeel, int32 wflags, DisplayDriver *ddriver);
|
||||
|
||||
// global function pointer
|
||||
create_decorator *make_decorator;
|
||||
|
||||
port_id fMessagePort;
|
||||
port_id fServerInputPort;
|
||||
|
||||
image_id fDecoratorID;
|
||||
|
||||
BString fDecoratorName;
|
||||
|
||||
volatile bool fQuittingServer;
|
||||
|
||||
BList *fAppList;
|
||||
@ -92,11 +82,7 @@ private:
|
||||
DisplayDriver *fDriver;
|
||||
};
|
||||
|
||||
Decorator *new_decorator(BRect rect, const char *title, int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver);
|
||||
|
||||
extern BitmapManager *bitmapmanager;
|
||||
extern ColorSet gui_colorset;
|
||||
extern AppServer *app_server;
|
||||
extern port_id gAppServerPort;
|
||||
|
||||
|
@ -1,854 +0,0 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2002, Haiku, Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// File Name: bget++.cpp
|
||||
// Author: John Walker <kelvin@fourmilab.ch>
|
||||
// DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Description: public domain BGET pool allocator converted to C++
|
||||
// Distributed with Haiku under MIT license
|
||||
//
|
||||
//------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
This class is based on the BGET pool allocator. Original code was in standard
|
||||
ANSI C with a bunch of static variables. The original code was placed into the
|
||||
MemPool class and the original allocation, release, and compacting functions
|
||||
were made into virtual members. MemPool also, unlike the original code, makes
|
||||
use of malloc() and free() to handle dynamic memory needs. AreaPool is a MemPool
|
||||
subclass which uses areas to handle memory management needs in large chunks.
|
||||
*/
|
||||
|
||||
|
||||
// Buffer allocation size quantum: all buffers allocated are a multiple of this size. '
|
||||
// This MUST be a power of two.
|
||||
#define SizeQuant 4
|
||||
|
||||
#include <stdio.h>
|
||||
#include <OS.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// Declare the interface, including the requested buffer size type, ssize_t.
|
||||
#include "BGet++.h"
|
||||
|
||||
// Queue links
|
||||
struct qlinks
|
||||
{
|
||||
struct bfhead *flink; // Forward link
|
||||
struct bfhead *blink; // Backward link
|
||||
};
|
||||
|
||||
// Header in allocated and free buffers
|
||||
struct bhead
|
||||
{
|
||||
// Relative link back to previous free buffer in memory or 0 if previous
|
||||
// buffer is allocated.
|
||||
ssize_t prevfree;
|
||||
|
||||
// Buffer size: positive if free, negative if allocated.
|
||||
ssize_t bsize;
|
||||
};
|
||||
|
||||
#define BH(p) ((struct bhead *) (p))
|
||||
|
||||
// Header in directly allocated buffers (by acqfcn)
|
||||
struct bdhead
|
||||
{
|
||||
ssize_t tsize; // Total size, including overhead
|
||||
struct bhead bh; // Common header
|
||||
};
|
||||
|
||||
#define BDH(p) ((struct bdhead *) (p))
|
||||
|
||||
// Header in free buffers
|
||||
struct bfhead
|
||||
{
|
||||
// Common allocated/free header
|
||||
struct bhead bh;
|
||||
|
||||
// Links on free list
|
||||
struct qlinks ql;
|
||||
};
|
||||
|
||||
#define BFH(p) ((struct bfhead *) (p))
|
||||
|
||||
static struct bfhead freelist =
|
||||
{
|
||||
// List of free buffers
|
||||
{0, 0},
|
||||
{&freelist, &freelist}
|
||||
};
|
||||
|
||||
|
||||
// Minimum allocation quantum:
|
||||
#define QLSize (sizeof(struct qlinks))
|
||||
#define SizeQ ((SizeQuant > QLSize) ? SizeQuant : QLSize)
|
||||
|
||||
// End sentinel: value placed in bsize field of dummy block delimiting end of
|
||||
// pool block. The most negative number which will fit in a ssize_t,
|
||||
// defined in a way that the compiler will accept.
|
||||
#define ESent ((ssize_t) (-(((1L << (sizeof(ssize_t) * 8 - 2)) - 1) * 2) - 2))
|
||||
|
||||
|
||||
MemPool::MemPool(void)
|
||||
: totalloc(0),
|
||||
numget(0),
|
||||
numrel(0),
|
||||
numpblk(0),
|
||||
numpget(0),
|
||||
numprel(0),
|
||||
numdget(0),
|
||||
numdrel(0),
|
||||
exp_incr(0),
|
||||
pool_len(0)
|
||||
{
|
||||
}
|
||||
|
||||
MemPool::~MemPool(void)
|
||||
{
|
||||
}
|
||||
|
||||
// Allocate a buffer from the available space in the memory pool
|
||||
void *MemPool::GetBuffer(ssize_t requested_size, bool zero)
|
||||
{
|
||||
ssize_t size = requested_size;
|
||||
struct bfhead *b;
|
||||
|
||||
struct bfhead *best;
|
||||
void *buf;
|
||||
|
||||
int compactseq = 0;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
if (size < (ssize_t)SizeQ)
|
||||
{
|
||||
// Need at least room for the queue links.
|
||||
size = SizeQ;
|
||||
}
|
||||
|
||||
#if SizeQuant > 1
|
||||
size = (size + (SizeQuant - 1)) & (~(SizeQuant - 1));
|
||||
#endif
|
||||
|
||||
// Add overhead in allocated buffer to size required.
|
||||
size += sizeof(struct bhead);
|
||||
|
||||
// If a compact function was provided in the call to bectl(), wrap
|
||||
// a loop around the allocation process to allow compaction to
|
||||
// intervene in case we don't find a suitable buffer in the chain.
|
||||
while (1)
|
||||
{
|
||||
b = freelist.ql.flink;
|
||||
best = &freelist;
|
||||
|
||||
|
||||
// Scan the free list searching for the first buffer big enough
|
||||
// to hold the requested size buffer.
|
||||
|
||||
while (b != &freelist)
|
||||
{
|
||||
if (b->bh.bsize >= size)
|
||||
{
|
||||
if ((best == &freelist) || (b->bh.bsize < best->bh.bsize))
|
||||
{
|
||||
best = b;
|
||||
}
|
||||
}
|
||||
|
||||
b = b->ql.flink; // Link to next buffer
|
||||
}
|
||||
b = best;
|
||||
|
||||
while (b != &freelist)
|
||||
{
|
||||
if ((ssize_t) b->bh.bsize >= size)
|
||||
{
|
||||
|
||||
// Buffer is big enough to satisfy the request. Allocate it to the caller.
|
||||
// We must decide whether the buffer is large enough to split into the part
|
||||
// given to the caller and a free buffer that remains on the free list, or
|
||||
// whether the entire buffer should be removed from the free list and given
|
||||
// to the caller in its entirety. We only split the buffer if enough room
|
||||
// remains for a header plus the minimum quantum of allocation.
|
||||
|
||||
if ((b->bh.bsize - size) > (ssize_t)(SizeQ + (sizeof(struct bhead))))
|
||||
{
|
||||
struct bhead *ba, *bn;
|
||||
|
||||
ba = BH(((char *) b) + (b->bh.bsize - size));
|
||||
bn = BH(((char *) ba) + size);
|
||||
assert(bn->prevfree == b->bh.bsize);
|
||||
|
||||
// Subtract size from length of free block.
|
||||
b->bh.bsize -= size;
|
||||
|
||||
// Link allocated buffer to the previous free buffer.
|
||||
ba->prevfree = b->bh.bsize;
|
||||
|
||||
// Plug negative size into user buffer.
|
||||
ba->bsize = -(ssize_t) size;
|
||||
|
||||
// Mark buffer after this one not preceded by free block.
|
||||
bn->prevfree = 0;
|
||||
|
||||
totalloc += size;
|
||||
numget++; // Increment number of GetBuffer() calls
|
||||
|
||||
buf = (void *) ((((char *) ba) + sizeof(struct bhead)));
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct bhead *ba;
|
||||
|
||||
ba = BH(((char *) b) + b->bh.bsize);
|
||||
assert(ba->prevfree == b->bh.bsize);
|
||||
|
||||
// The buffer isn't big enough to split. Give the whole
|
||||
// shebang to the caller and remove it from the free list.
|
||||
|
||||
assert(b->ql.blink->ql.flink == b);
|
||||
assert(b->ql.flink->ql.blink == b);
|
||||
b->ql.blink->ql.flink = b->ql.flink;
|
||||
b->ql.flink->ql.blink = b->ql.blink;
|
||||
|
||||
totalloc += b->bh.bsize;
|
||||
numget++; // Increment number of GetBuffer() calls
|
||||
|
||||
// Negate size to mark buffer allocated.
|
||||
b->bh.bsize = -(b->bh.bsize);
|
||||
|
||||
// Zero the back pointer in the next buffer in memory
|
||||
// to indicate that this buffer is allocated.
|
||||
ba->prevfree = 0;
|
||||
|
||||
// Give user buffer starting at queue links.
|
||||
buf = (void *) &(b->ql);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
b = b->ql.flink; // Link to next buffer
|
||||
}
|
||||
|
||||
|
||||
// We failed to find a buffer. If there's a compact function
|
||||
// defined, notify it of the size requested. If it returns
|
||||
// TRUE, try the allocation again.
|
||||
|
||||
if(!CompactMem(size, ++compactseq))
|
||||
break;
|
||||
}
|
||||
|
||||
// No buffer available with requested size free.
|
||||
|
||||
// Don't give up yet -- look in the reserve supply.
|
||||
if (size > (ssize_t)(exp_incr - sizeof(struct bhead)))
|
||||
{
|
||||
// Request is too large to fit in a single expansion
|
||||
// block. Try to satisy it by a direct buffer acquisition.
|
||||
struct bdhead *bdh;
|
||||
|
||||
size += sizeof(struct bdhead) - sizeof(struct bhead);
|
||||
if ((bdh = BDH(AcquireMem((ssize_t) size))) != NULL)
|
||||
{
|
||||
// Mark the buffer special by setting the size field
|
||||
// of its header to zero.
|
||||
bdh->bh.bsize = 0;
|
||||
bdh->bh.prevfree = 0;
|
||||
bdh->tsize = size;
|
||||
|
||||
totalloc += size;
|
||||
|
||||
// Increment number of GetBuffer() calls
|
||||
numget++;
|
||||
|
||||
// Direct GetBuffer() call count
|
||||
numdget++;
|
||||
|
||||
buf = (void *) (bdh + 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Try to obtain a new expansion block
|
||||
void *newpool;
|
||||
|
||||
if ((newpool = AcquireMem((ssize_t) exp_incr)) != NULL)
|
||||
{
|
||||
AddToPool(newpool, exp_incr);
|
||||
|
||||
// This can't, I say, can't get into a loop
|
||||
buf = GetBuffer(requested_size);
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
// Still no buffer available
|
||||
return NULL;
|
||||
|
||||
// Code from bgetz -- zeroing code
|
||||
/*
|
||||
char *buf = (char *) GetBuffer(size);
|
||||
|
||||
if (buf != NULL)
|
||||
{
|
||||
struct bhead *b;
|
||||
ssize_t rsize;
|
||||
|
||||
b = BH(buf - sizeof(struct bhead));
|
||||
rsize = -(b->bsize);
|
||||
|
||||
if (rsize == 0)
|
||||
{
|
||||
struct bdhead *bd;
|
||||
|
||||
bd = BDH(buf - sizeof(struct bdhead));
|
||||
rsize = bd->tsize - sizeof(struct bdhead);
|
||||
}
|
||||
else
|
||||
{
|
||||
rsize -= sizeof(struct bhead);
|
||||
}
|
||||
|
||||
assert(rsize >= size);
|
||||
memset(buf, 0, (MemSize) rsize);
|
||||
}
|
||||
return ((void *) buf);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
// Reallocate a buffer. This is a minimal implementation, simply in terms
|
||||
// of ReleaseBuffer() and GetBuffer(). It could be enhanced to allow the
|
||||
// buffer to grow into adjacent free blocks and to avoid moving data unnecessarily.
|
||||
void *MemPool::ReallocateBuffer(void *buf, ssize_t size)
|
||||
{
|
||||
void *nbuf;
|
||||
|
||||
// Old size of buffer
|
||||
ssize_t osize;
|
||||
struct bhead *b;
|
||||
|
||||
if ((nbuf = GetBuffer(size)) == NULL)
|
||||
{
|
||||
// Acquire new buffer
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
return nbuf;
|
||||
}
|
||||
b = BH(((char *) buf) - sizeof(struct bhead));
|
||||
osize = -b->bsize;
|
||||
|
||||
if (osize == 0)
|
||||
{
|
||||
// Buffer acquired directly through acqfcn.
|
||||
struct bdhead *bd;
|
||||
|
||||
bd = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||
osize = bd->tsize - sizeof(struct bdhead);
|
||||
}
|
||||
else
|
||||
osize -= sizeof(struct bhead);
|
||||
assert(osize > 0);
|
||||
|
||||
// Copy the data
|
||||
memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize));
|
||||
ReleaseBuffer(buf);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
// BREL -- Release a buffer.
|
||||
void MemPool::ReleaseBuffer(void *buf)
|
||||
{
|
||||
struct bfhead *b, *bn;
|
||||
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
|
||||
// Increment number of ReleaseBuffer() calls
|
||||
numrel++;
|
||||
|
||||
assert(buf != NULL);
|
||||
|
||||
// Directly-acquired buffer?
|
||||
if (b->bh.bsize == 0)
|
||||
{
|
||||
struct bdhead *bdh;
|
||||
|
||||
bdh = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||
assert(b->bh.prevfree == 0);
|
||||
|
||||
totalloc -= bdh->tsize;
|
||||
assert(totalloc >= 0);
|
||||
|
||||
// Number of direct releases
|
||||
numdrel++;
|
||||
|
||||
memset((char *) buf, 0x55, (int) (bdh->tsize - sizeof(struct bdhead)));
|
||||
|
||||
// Release it directly.
|
||||
ReleaseMem((void *) bdh);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Buffer size must be negative, indicating that the buffer is allocated.
|
||||
if (b->bh.bsize >= 0)
|
||||
{
|
||||
bn = NULL;
|
||||
}
|
||||
assert(b->bh.bsize < 0);
|
||||
|
||||
// Back pointer in next buffer must be zero, indicating the same thing:
|
||||
assert(BH((char *) b - b->bh.bsize)->prevfree == 0);
|
||||
|
||||
totalloc += b->bh.bsize;
|
||||
assert(totalloc >= 0);
|
||||
|
||||
|
||||
// If the back link is nonzero, the previous buffer is free.
|
||||
|
||||
if (b->bh.prevfree != 0)
|
||||
{
|
||||
// The previous buffer is free. Consolidate this buffer with it
|
||||
// by adding the length of this buffer to the previous free
|
||||
// buffer. Note that we subtract the size in the buffer being
|
||||
// released, since it's negative to indicate that the buffer is allocated.
|
||||
|
||||
register ssize_t size = b->bh.bsize;
|
||||
|
||||
// Make the previous buffer the one we're working on.
|
||||
assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree);
|
||||
b = BFH(((char *) b) - b->bh.prevfree);
|
||||
b->bh.bsize -= size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The previous buffer isn't allocated. Insert this buffer on the
|
||||
// free list as an isolated free block.
|
||||
assert(freelist.ql.blink->ql.flink == &freelist);
|
||||
assert(freelist.ql.flink->ql.blink == &freelist);
|
||||
b->ql.flink = &freelist;
|
||||
b->ql.blink = freelist.ql.blink;
|
||||
freelist.ql.blink = b;
|
||||
b->ql.blink->ql.flink = b;
|
||||
b->bh.bsize = -b->bh.bsize;
|
||||
}
|
||||
|
||||
// Now we look at the next buffer in memory, located by advancing from
|
||||
// the start of this buffer by its size, to see if that buffer is
|
||||
// free. If it is, we combine this buffer with the next one in
|
||||
// memory, dechaining the second buffer from the free list.
|
||||
|
||||
bn = BFH(((char *) b) + b->bh.bsize);
|
||||
if (bn->bh.bsize > 0)
|
||||
{
|
||||
// The buffer is free. Remove it from the free list and add
|
||||
// its size to that of our buffer.
|
||||
assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize);
|
||||
assert(bn->ql.blink->ql.flink == bn);
|
||||
assert(bn->ql.flink->ql.blink == bn);
|
||||
bn->ql.blink->ql.flink = bn->ql.flink;
|
||||
bn->ql.flink->ql.blink = bn->ql.blink;
|
||||
b->bh.bsize += bn->bh.bsize;
|
||||
|
||||
// Finally, advance to the buffer that follows the newly
|
||||
// consolidated free block. We must set its backpointer to the
|
||||
// head of the consolidated free block. We know the next block
|
||||
// must be an allocated block because the process of recombination
|
||||
// guarantees that two free blocks will never be contiguous in
|
||||
// memory.
|
||||
bn = BFH(((char *) b) + b->bh.bsize);
|
||||
}
|
||||
|
||||
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (b->bh.bsize - sizeof(struct bfhead)));
|
||||
|
||||
assert(bn->bh.bsize < 0);
|
||||
|
||||
// The next buffer is allocated. Set the backpointer in it to point
|
||||
// to this buffer; the previous free buffer in memory.
|
||||
bn->bh.prevfree = b->bh.bsize;
|
||||
|
||||
// If a block-release function is defined, and this free buffer
|
||||
// constitutes the entire block, release it. Note that pool_len
|
||||
// is defined in such a way that the test will fail unless all
|
||||
// pool blocks are the same size.
|
||||
|
||||
if (((ssize_t) b->bh.bsize) == (ssize_t)(pool_len - sizeof(struct bhead)))
|
||||
{
|
||||
assert(b->bh.prevfree == 0);
|
||||
assert(BH((char *) b + b->bh.bsize)->bsize == ESent);
|
||||
assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);
|
||||
|
||||
// Unlink the buffer from the free list
|
||||
b->ql.blink->ql.flink = b->ql.flink;
|
||||
b->ql.flink->ql.blink = b->ql.blink;
|
||||
|
||||
ReleaseMem(b);
|
||||
|
||||
// Nr of expansion block releases
|
||||
numprel++;
|
||||
|
||||
// Total number of blocks
|
||||
numpblk--;
|
||||
assert(numpblk == numpget - numprel);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a region of memory to the buffer pool.
|
||||
void MemPool::AddToPool(void *buf, ssize_t len)
|
||||
{
|
||||
struct bfhead *b = BFH(buf);
|
||||
struct bhead *bn;
|
||||
|
||||
len &= ~(SizeQuant - 1);
|
||||
|
||||
if (pool_len == 0)
|
||||
{
|
||||
pool_len = len;
|
||||
}
|
||||
else
|
||||
if (len != pool_len)
|
||||
{
|
||||
pool_len = -1;
|
||||
}
|
||||
|
||||
// Number of block acquisitions
|
||||
numpget++;
|
||||
|
||||
// Number of blocks total
|
||||
numpblk++;
|
||||
assert(numpblk == numpget - numprel);
|
||||
|
||||
// Since the block is initially occupied by a single free buffer,
|
||||
// it had better not be (much) larger than the largest buffer
|
||||
// whose size we can store in bhead.bsize.
|
||||
assert(len - sizeof(struct bhead) <= -((ssize_t) ESent + 1));
|
||||
|
||||
// Clear the backpointer at the start of the block to indicate that
|
||||
// there is no free block prior to this one. That blocks
|
||||
// recombination when the first block in memory is released.
|
||||
b->bh.prevfree = 0;
|
||||
|
||||
// Chain the new block to the free list.
|
||||
assert(freelist.ql.blink->ql.flink == &freelist);
|
||||
assert(freelist.ql.flink->ql.blink == &freelist);
|
||||
b->ql.flink = &freelist;
|
||||
b->ql.blink = freelist.ql.blink;
|
||||
freelist.ql.blink = b;
|
||||
b->ql.blink->ql.flink = b;
|
||||
|
||||
// Create a dummy allocated buffer at the end of the pool. This dummy
|
||||
// buffer is seen when a buffer at the end of the pool is released and
|
||||
// blocks recombination of the last buffer with the dummy buffer at
|
||||
// the end. The length in the dummy buffer is set to the largest
|
||||
// negative number to denote the end of the pool for diagnostic
|
||||
// routines (this specific value is not counted on by the actual
|
||||
// allocation and release functions).
|
||||
|
||||
len -= sizeof(struct bhead);
|
||||
b->bh.bsize = (ssize_t) len;
|
||||
|
||||
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (len - sizeof(struct bfhead)));
|
||||
|
||||
bn = BH(((char *) b) + len);
|
||||
bn->prevfree = (ssize_t) len;
|
||||
|
||||
// Definition of ESent assumes two's complement!
|
||||
assert((~0) == -1);
|
||||
bn->bsize = ESent;
|
||||
}
|
||||
|
||||
|
||||
// Return buffer allocation free space statistics.
|
||||
void MemPool::Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree,
|
||||
long *nget, long *nrel)
|
||||
{
|
||||
struct bfhead *b = freelist.ql.flink;
|
||||
|
||||
*nget = numget;
|
||||
*nrel = numrel;
|
||||
*curalloc = totalloc;
|
||||
*totfree = 0;
|
||||
*maxfree = -1;
|
||||
while (b != &freelist)
|
||||
{
|
||||
assert(b->bh.bsize > 0);
|
||||
*totfree += b->bh.bsize;
|
||||
if (b->bh.bsize > *maxfree)
|
||||
{
|
||||
*maxfree = b->bh.bsize;
|
||||
}
|
||||
|
||||
// Link to next buffer
|
||||
b = b->ql.flink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return extended statistics
|
||||
void MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget, long *nprel,
|
||||
long *ndget, long *ndrel)
|
||||
{
|
||||
*pool_incr = (pool_len < 0) ? -exp_incr : exp_incr;
|
||||
*npool = numpblk;
|
||||
*npget = numpget;
|
||||
*nprel = numprel;
|
||||
*ndget = numdget;
|
||||
*ndrel = numdrel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Dump the data in a buffer. This is called with the user data pointer,
|
||||
// and backs up to the buffer header. It will dump either a free block
|
||||
// or an allocated one.
|
||||
void MemPool::BufferDump(void *buf)
|
||||
{
|
||||
struct bfhead *b;
|
||||
unsigned char *bdump;
|
||||
ssize_t bdlen;
|
||||
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
assert(b->bh.bsize != 0);
|
||||
if (b->bh.bsize < 0)
|
||||
{
|
||||
bdump = (unsigned char *) buf;
|
||||
bdlen = (-b->bh.bsize) - sizeof(struct bhead);
|
||||
}
|
||||
else
|
||||
{
|
||||
bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));
|
||||
bdlen = b->bh.bsize - sizeof(struct bfhead);
|
||||
}
|
||||
|
||||
while (bdlen > 0)
|
||||
{
|
||||
int i, dupes = 0;
|
||||
ssize_t l = bdlen;
|
||||
char bhex[50], bascii[20];
|
||||
|
||||
if (l > 16)
|
||||
{
|
||||
l = 16;
|
||||
}
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
sprintf(bhex + i * 3, "%02X ", bdump[i]);
|
||||
bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
|
||||
}
|
||||
bascii[i] = 0;
|
||||
printf("%-48s %s\n", bhex, bascii);
|
||||
bdump += l;
|
||||
bdlen -= l;
|
||||
while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0))
|
||||
{
|
||||
dupes++;
|
||||
bdump += 16;
|
||||
bdlen -= 16;
|
||||
}
|
||||
|
||||
if (dupes > 1)
|
||||
{
|
||||
printf(" (%d lines [%d bytes] identical to above line skipped)\n",
|
||||
dupes, dupes * 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dupes == 1)
|
||||
{
|
||||
bdump -= 16;
|
||||
bdlen += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dump a buffer pool. The buffer headers are always listed. If DUMPALLOC is
|
||||
// nonzero, the contents of allocated buffers are dumped. If DUMPFREE is
|
||||
// nonzero, free blocks are dumped as well. If FreeWipe checking is enabled,
|
||||
// free blocks which have been clobbered will always be dumped.
|
||||
void MemPool::PoolDump(void *buf, bool dumpalloc, bool dumpfree)
|
||||
{
|
||||
struct bfhead *b = BFH(buf);
|
||||
|
||||
while (b->bh.bsize != ESent)
|
||||
{
|
||||
ssize_t bs = b->bh.bsize;
|
||||
|
||||
if (bs < 0)
|
||||
{
|
||||
bs = -bs;
|
||||
printf("Allocated buffer: size %6ld bytes.\n", (long) bs);
|
||||
if (dumpalloc)
|
||||
{
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lerr = "";
|
||||
|
||||
assert(bs > 0);
|
||||
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||
{
|
||||
lerr = " (Bad free list links)";
|
||||
}
|
||||
printf("Free block: size %6ld bytes.%s\n",
|
||||
(long) bs, lerr);
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||
(memcmp(lerr, lerr + 1, (int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||
{
|
||||
printf("(Contents of above free block have been overstored.)\n");
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dumpfree)
|
||||
{
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
}
|
||||
}
|
||||
b = BFH(((char *) b) + bs);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate a buffer pool.
|
||||
int MemPool::Validate(void *buf)
|
||||
{
|
||||
struct bfhead *b = BFH(buf);
|
||||
|
||||
while (b->bh.bsize != ESent)
|
||||
{
|
||||
ssize_t bs = b->bh.bsize;
|
||||
|
||||
if (bs < 0)
|
||||
{
|
||||
bs = -bs;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lerr = "";
|
||||
|
||||
assert(bs > 0);
|
||||
if (bs <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||
{
|
||||
printf("Free block: size %6ld bytes. (Bad free list links)\n",
|
||||
(long) bs);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||
(memcmp(lerr, lerr + 1,(int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||
{
|
||||
printf("(Contents of above free block have been overstored.)\n");
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
b = BFH(((char *) b) + bs);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int *MemPool::CompactMem(ssize_t sizereq, int sequence)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *MemPool::AcquireMem(ssize_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void MemPool::ReleaseMem(void *buffer)
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
AreaPool::AreaPool(void)
|
||||
{
|
||||
}
|
||||
|
||||
AreaPool::~AreaPool(void)
|
||||
{
|
||||
}
|
||||
|
||||
void *AreaPool::AcquireMem(ssize_t size)
|
||||
{
|
||||
long areasize=0;
|
||||
area_id a;
|
||||
int *parea;
|
||||
|
||||
if(size<B_PAGE_SIZE)
|
||||
areasize=B_PAGE_SIZE;
|
||||
else
|
||||
{
|
||||
if((size % B_PAGE_SIZE)!=0)
|
||||
areasize=((long)(size/B_PAGE_SIZE)+1)*B_PAGE_SIZE;
|
||||
else
|
||||
areasize=size;
|
||||
}
|
||||
|
||||
a=create_area("AreaPool_area",(void**)&parea,B_ANY_ADDRESS,areasize,
|
||||
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
|
||||
if(a==B_BAD_VALUE || a==B_NO_MEMORY || a==B_ERROR)
|
||||
{
|
||||
printf("ERROR: AreaPool couldn't allocate area!!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parea;
|
||||
}
|
||||
|
||||
void AreaPool::ReleaseMem(void *buffer)
|
||||
{
|
||||
area_id trash=area_for(buffer);
|
||||
|
||||
if(trash==B_ERROR)
|
||||
return;
|
||||
|
||||
delete_area(trash);
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
#ifndef HGET_H_
|
||||
#define HGET_H_
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class MemPool
|
||||
{
|
||||
public:
|
||||
MemPool(void);
|
||||
virtual ~MemPool(void);
|
||||
|
||||
void AddToPool(void *buffer, ssize_t len);
|
||||
void *GetBuffer(ssize_t size, bool zero=false);
|
||||
void *ReallocateBuffer(void *buffer, ssize_t size);
|
||||
void ReleaseBuffer(void *buffer);
|
||||
|
||||
virtual int *CompactMem(ssize_t sizereq, int sequence);
|
||||
virtual void *AcquireMem(ssize_t size);
|
||||
virtual void ReleaseMem(void *buffer);
|
||||
void SetPoolIncrement(ssize_t increment);
|
||||
ssize_t PoolIncrement(void);
|
||||
|
||||
void Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree,
|
||||
long *nget, long *nrel);
|
||||
|
||||
void ExtendedStats(ssize_t *pool_incr, long *npool, long *npget,
|
||||
long *nprel, long *ndget, long *ndrel);
|
||||
|
||||
void BufferDump(void *buf);
|
||||
void PoolDump(void *pool, bool dumpalloc, bool dumpfree);
|
||||
int Validate(void *buffer);
|
||||
|
||||
private:
|
||||
ssize_t totalloc;
|
||||
long numget, numrel;
|
||||
long numpblk;
|
||||
long numpget, numprel;
|
||||
long numdget, numdrel;
|
||||
ssize_t exp_incr;
|
||||
ssize_t pool_len;
|
||||
|
||||
};
|
||||
|
||||
class AreaPool : public MemPool
|
||||
{
|
||||
public:
|
||||
AreaPool(void);
|
||||
virtual ~AreaPool(void);
|
||||
virtual void *AcquireMem(ssize_t size);
|
||||
virtual void ReleaseMem(void *buffer);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,7 +1,8 @@
|
||||
SubDir HAIKU_TOP src tests apps fake_app_server ;
|
||||
|
||||
UseLibraryHeaders agg png zlib ;
|
||||
UsePrivateHeaders app interface shared [ FDirName servers app ] ;
|
||||
UsePrivateHeaders app interface shared ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes ] ;
|
||||
@ -11,6 +12,5 @@ UseFreeTypeHeaders ;
|
||||
Server fake_app_server :
|
||||
AppServer.cpp
|
||||
ServerApp.cpp
|
||||
BGet++.cpp
|
||||
: libroot.so libbe.so
|
||||
: be
|
||||
;
|
||||
|
@ -14,23 +14,13 @@
|
||||
#include <AppDefs.h>
|
||||
#include <List.h>
|
||||
#include <String.h>
|
||||
#include <ColorSet.h>
|
||||
#include <RGBColor.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <Shape.h>
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "BitmapManager.h"
|
||||
#include "BGet++.h"
|
||||
|
||||
#include "ServerApp.h"
|
||||
#include "ServerCursor.h"
|
||||
#include "ServerBitmap.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "SystemPalette.h"
|
||||
|
||||
//#define DEBUG_SERVERAPP
|
||||
|
||||
@ -67,15 +57,9 @@ ServerApp::ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort
|
||||
fMonitorThreadID(-1),
|
||||
fClientTeamID(clientTeamID),
|
||||
fLink(fClientAppPort, fMessagePort),
|
||||
fSWindowList(new BList()),
|
||||
fBitmapList(new BList()),
|
||||
fPictureList(new BList()),
|
||||
fAppCursor(NULL),
|
||||
fLockSem(create_sem(1, "ServerApp sem")),
|
||||
fCursorHidden(false),
|
||||
fIsActive(false),
|
||||
//fHandlerToken(handlerID),
|
||||
fSharedMem(new AreaPool),
|
||||
fQuitting(false)
|
||||
{
|
||||
if (fSignature == "")
|
||||
@ -95,9 +79,6 @@ ServerApp::~ServerApp(void)
|
||||
STRACE(("*ServerApp %s:~ServerApp()\n",fSignature.String()));
|
||||
|
||||
fQuitting = true;
|
||||
|
||||
delete fBitmapList;
|
||||
delete fPictureList;
|
||||
|
||||
// This shouldn't be necessary -- all cursors owned by the app
|
||||
// should be cleaned up by RemoveAppCursors
|
||||
@ -117,8 +98,6 @@ ServerApp::~ServerApp(void)
|
||||
status_t dummyStatus;
|
||||
wait_for_thread(fMonitorThreadID, &dummyStatus);
|
||||
|
||||
delete fSharedMem;
|
||||
|
||||
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", fSignature.String()));
|
||||
}
|
||||
|
||||
@ -206,14 +185,6 @@ void
|
||||
ServerApp::Activate(bool value)
|
||||
{
|
||||
fIsActive = value;
|
||||
SetAppCursor();
|
||||
}
|
||||
|
||||
|
||||
//! Sets the cursor to the application cursor, if any.
|
||||
void
|
||||
ServerApp::SetAppCursor(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -300,74 +271,6 @@ void
|
||||
ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
{
|
||||
switch (code) {
|
||||
case AS_ACQUIRE_SERVERMEM:
|
||||
{
|
||||
// This particular call is more than a bit of a pain in the neck. We are given a
|
||||
// size of a chunk of memory needed. We need to (1) allocate it, (2) get the area for
|
||||
// this particular chunk, (3) find the offset in the area for this chunk, and (4)
|
||||
// tell the client about it. Good thing this particular call isn't used much
|
||||
|
||||
// Received from a ServerMemIO object requesting operating memory
|
||||
// Attached Data:
|
||||
// 1) size_t requested size
|
||||
// 2) port_id reply_port
|
||||
|
||||
size_t memsize;
|
||||
link.Read<size_t>(&memsize);
|
||||
|
||||
// TODO: I wonder if ACQUIRE_SERVERMEM should have a minimum size requirement?
|
||||
|
||||
void *sharedmem = fSharedMem->GetBuffer(memsize);
|
||||
|
||||
if (memsize < 1 || sharedmem == NULL) {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
|
||||
area_id owningArea = area_for(sharedmem);
|
||||
area_info info;
|
||||
|
||||
if (owningArea == B_ERROR || get_area_info(owningArea, &info) < B_OK) {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
|
||||
int32 areaoffset = (addr_t)sharedmem - (addr_t)info.address;
|
||||
STRACE(("Successfully allocated shared memory of size %ld\n",memsize));
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<area_id>(owningArea);
|
||||
fLink.Attach<int32>(areaoffset);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_RELEASE_SERVERMEM:
|
||||
{
|
||||
// Received when a ServerMemIO object on destruction
|
||||
// Attached Data:
|
||||
// 1) area_id owning area
|
||||
// 2) int32 area offset
|
||||
|
||||
area_id owningArea;
|
||||
int32 areaoffset;
|
||||
|
||||
link.Read<area_id>(&owningArea);
|
||||
link.Read<int32>(&areaoffset);
|
||||
|
||||
area_info areaInfo;
|
||||
if (owningArea < 0 || get_area_info(owningArea, &areaInfo) != B_OK)
|
||||
break;
|
||||
|
||||
STRACE(("Successfully freed shared memory\n"));
|
||||
void *sharedmem = ((int32*)areaInfo.address) + areaoffset;
|
||||
|
||||
fSharedMem->ReleaseBuffer(sharedmem);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AS_CURRENT_WORKSPACE:
|
||||
{
|
||||
STRACE(("ServerApp %s: get current workspace\n", fSignature.String()));
|
||||
@ -416,46 +319,6 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ServerApp::CountBitmaps() const
|
||||
{
|
||||
return fBitmapList ? fBitmapList->CountItems() : 0;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Looks up a ServerApp's ServerBitmap in its list
|
||||
\param token ID token of the bitmap to find
|
||||
\return The bitmap having that ID or NULL if not found
|
||||
*/
|
||||
ServerBitmap *
|
||||
ServerApp::FindBitmap(int32 token) const
|
||||
{
|
||||
ServerBitmap *bitmap;
|
||||
for (int32 i = 0; i < fBitmapList->CountItems(); i++) {
|
||||
bitmap = static_cast<ServerBitmap *>(fBitmapList->ItemAt(i));
|
||||
if (bitmap && bitmap->Token() == token)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ServerApp::CountPictures() const
|
||||
{
|
||||
return fPictureList ? fPictureList->CountItems() : 0;
|
||||
}
|
||||
|
||||
|
||||
ServerPicture *
|
||||
ServerApp::FindPicture(int32 token) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
team_id
|
||||
ServerApp::ClientTeamID() const
|
||||
{
|
||||
|
@ -32,13 +32,9 @@
|
||||
#include <String.h>
|
||||
#include <PortLink.h>
|
||||
|
||||
class AreaPool;
|
||||
class BMessage;
|
||||
class BList;
|
||||
class DisplayDriver;
|
||||
class ServerPicture;
|
||||
class ServerCursor;
|
||||
class ServerBitmap;
|
||||
|
||||
namespace BPrivate {
|
||||
class PortLink;
|
||||
@ -55,16 +51,7 @@ public:
|
||||
virtual ~ServerApp(void);
|
||||
|
||||
bool Run(void);
|
||||
/*
|
||||
TODO: These aren't even implemented...
|
||||
void Lock(void);
|
||||
void Unlock(void);
|
||||
bool IsLocked(void);
|
||||
*/
|
||||
/*!
|
||||
\brief Determines whether the application is the active one
|
||||
\return true if active, false if not.
|
||||
*/
|
||||
|
||||
bool IsActive(void) const { return fIsActive; }
|
||||
void Activate(bool value);
|
||||
|
||||
@ -72,22 +59,12 @@ public:
|
||||
|
||||
void PostMessage(int32 code);
|
||||
void SendMessageToClient( const BMessage* msg ) const;
|
||||
|
||||
void SetAppCursor(void);
|
||||
|
||||
|
||||
team_id ClientTeamID() const;
|
||||
thread_id MonitorThreadID() const;
|
||||
|
||||
const char *Title() const { return fSignature.String(); }
|
||||
|
||||
int32 CountBitmaps() const;
|
||||
ServerBitmap *FindBitmap(int32 token) const;
|
||||
|
||||
int32 CountPictures() const;
|
||||
ServerPicture *FindPicture(int32 token) const;
|
||||
|
||||
AreaPool *AppAreaPool() { return fSharedMem; }
|
||||
|
||||
private:
|
||||
void DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
|
||||
@ -113,12 +90,8 @@ private:
|
||||
// TODO:
|
||||
// - Are really Bitmaps and Pictures stored per application and not globally ?
|
||||
// - As we reference these stuff by token, what about putting them in hash tables ?
|
||||
BList *fSWindowList,
|
||||
*fBitmapList,
|
||||
*fPictureList;
|
||||
|
||||
ServerCursor *fAppCursor;
|
||||
|
||||
BList *fSWindowList;
|
||||
|
||||
// TODO: Not used.
|
||||
sem_id fLockSem;
|
||||
|
||||
@ -130,8 +103,6 @@ private:
|
||||
// TODO: Is it still needed ? We aren't using it.
|
||||
//int32 fHandlerToken;
|
||||
|
||||
AreaPool *fSharedMem;
|
||||
|
||||
bool fQuitting;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user