Added new FlushWithReply method and some error checking. Mostly tested.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2010 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+150
-8
@@ -28,6 +28,15 @@ capacity - contains the storage capacity of the target port.
|
||||
#include <malloc.h>
|
||||
|
||||
//#define PLDEBUG
|
||||
//#define PLD_DEBUG
|
||||
|
||||
#ifdef PLDEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef PLD_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// Internal data storage class for holding attached data whilst it is waiting
|
||||
// to be Flattened() and then Flushed(). There is no need for this to be called outside
|
||||
@@ -44,6 +53,9 @@ public:
|
||||
|
||||
PortLink::PortLink(port_id port)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink(%lu)\n",port);
|
||||
#endif
|
||||
// For this class to be useful (and to prevent a lot of init problems)
|
||||
// we require a port in the constructor
|
||||
target=port;
|
||||
@@ -62,6 +74,9 @@ PortLink::PortLink(port_id port)
|
||||
|
||||
PortLink::PortLink(const PortLink &link)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink(PortLink*)\n");
|
||||
#endif
|
||||
// The copy constructor copies everything except a PortLink's attachments. If there
|
||||
// is some reason why someday I might need to change this behavior, I will, but
|
||||
// for now there is no real reason I can think of.
|
||||
@@ -78,11 +93,15 @@ PortLink::PortLink(const PortLink &link)
|
||||
|
||||
PortLink::~PortLink(void)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("~PortLink()\n");
|
||||
#endif
|
||||
// If, for some odd reason, this is deleted with something attached,
|
||||
// free the memory used by the attachments. We do not flush the queue
|
||||
// because the port may no longer be valid in cases such as the app
|
||||
// is in the process of quitting
|
||||
MakeEmpty();
|
||||
if(num_attachments || bufferlength)
|
||||
MakeEmpty();
|
||||
|
||||
//TODO: Inline the MakeEmpty call in a way such that it ignores num_attachments
|
||||
// and deletes all non-NULL pointers, setting them to NULL afterward.
|
||||
@@ -90,6 +109,9 @@ PortLink::~PortLink(void)
|
||||
|
||||
void PortLink::SetOpCode(int32 code)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::SetOpCode(%lu)\n",code);
|
||||
#endif
|
||||
// Sets the message code. This does not change once the message is sent.
|
||||
// Another call to SetOpCode() is required for such things.
|
||||
opcode=code;
|
||||
@@ -97,6 +119,9 @@ void PortLink::SetOpCode(int32 code)
|
||||
|
||||
void PortLink::SetPort(port_id port)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::SetPort(%lu)\n",port);
|
||||
#endif
|
||||
// Sets the target port. While not necessary in most uses, this exists
|
||||
// mostly to prevent flexibility problems
|
||||
target=port;
|
||||
@@ -107,22 +132,36 @@ void PortLink::SetPort(port_id port)
|
||||
|
||||
port_id PortLink::GetPort(void)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::GetPort() returned %lu\n",target);
|
||||
#endif
|
||||
// Simply returns the port at which the object is pointed.
|
||||
return target;
|
||||
}
|
||||
|
||||
status_t PortLink::Flush(bigtime_t timeout=B_INFINITE_TIMEOUT)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::Flush()\n");
|
||||
#endif
|
||||
// Fires a message off to the target, complete with attachments.
|
||||
int8 *msgbuffer;
|
||||
int32 size;
|
||||
status_t write_stat=B_OK;
|
||||
|
||||
if(!port_ok)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlush(): invalid port\n");
|
||||
#endif
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if(num_attachments>0)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlush(): flushing %d attachments\n",num_attachments);
|
||||
#endif
|
||||
FlattenData(&msgbuffer,&size);
|
||||
|
||||
// Dump message to port, reset attachments, and clean up
|
||||
@@ -134,6 +173,9 @@ status_t PortLink::Flush(bigtime_t timeout=B_INFINITE_TIMEOUT)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlush(): flushing without attachments\n");
|
||||
#endif
|
||||
if(timeout!=B_INFINITE_TIMEOUT)
|
||||
write_stat=write_port_etc(target,opcode,NULL,0,B_TIMEOUT, timeout);
|
||||
else
|
||||
@@ -146,15 +188,23 @@ status_t PortLink::Flush(bigtime_t timeout=B_INFINITE_TIMEOUT)
|
||||
int8* PortLink::FlushWithReply(int32 *code, status_t *status, ssize_t *buffersize, bigtime_t timeout=B_INFINITE_TIMEOUT)
|
||||
{
|
||||
// Deprecated call which functions exactly like PortLink(PortLink::ReplyData *data)
|
||||
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::FlushWithReply(int32*,status_t*,ssize_t*,bigtime_t)\n");
|
||||
#endif
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::FlushWithReply(): too many attachments\n");
|
||||
#endif
|
||||
*status=B_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!port_ok)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::FlushWithReply(): bad port\n");
|
||||
#endif
|
||||
*status=B_BAD_VALUE;
|
||||
return NULL;
|
||||
}
|
||||
@@ -223,9 +273,11 @@ int8* PortLink::FlushWithReply(int32 *code, status_t *status, ssize_t *buffersiz
|
||||
}
|
||||
|
||||
|
||||
// TODO: write test code
|
||||
status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_INFINITE_TIMEOUT)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::FlushWithReply(ReplyData*,bigtime_t)\n");
|
||||
#endif
|
||||
// Fires a message to the target and then waits for a reply. The target will
|
||||
// receive a message with the first item being the port_id to reply to.
|
||||
// NOTE: like Flush(), any attached data must be deleted.
|
||||
@@ -233,19 +285,32 @@ status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_
|
||||
// Effectively, an Attach() call inlined for changes
|
||||
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlushWithReply(): too many attachments\n");
|
||||
#endif
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if(!port_ok)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlushWithReply(): invalid port\n");
|
||||
#endif
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// create a new storage object and stash the data
|
||||
PortLinkData *pld=new PortLinkData;
|
||||
if(pld->Set(&replyport,sizeof(port_id)))
|
||||
if(pld->Set(&replyport,sizeof(port_id))==B_OK)
|
||||
{
|
||||
bufferlength+=sizeof(port_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tFlushWithReply(): unable to assign reply port to data\n");
|
||||
#endif
|
||||
delete pld;
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -280,7 +345,7 @@ status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_
|
||||
data->buffersize=port_buffer_size(replyport);
|
||||
if(data->buffersize>0)
|
||||
data->buffer=(int8*)new int8[data->buffersize];
|
||||
read_port(replyport,&(data->code),&(data->buffer), data->buffersize);
|
||||
read_port(replyport,&(data->code),data->buffer, data->buffersize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -290,7 +355,7 @@ status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_
|
||||
|
||||
if(data->buffersize>0)
|
||||
data->buffer=(int8*)new int8[data->buffersize];
|
||||
read_port(replyport,&(data->code),&(data->buffer), data->buffersize);
|
||||
read_port(replyport,&(data->code),data->buffer, data->buffersize);
|
||||
}
|
||||
|
||||
// We got this far, so we apparently have some data
|
||||
@@ -299,32 +364,59 @@ status_t PortLink::FlushWithReply(PortLink::ReplyData *data,bigtime_t timeout=B_
|
||||
|
||||
status_t PortLink::Attach(void *data, size_t size)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%p,%ld)\n",data,size);
|
||||
#endif
|
||||
// This is the member called to attach data to a message. Attachments are
|
||||
// treated to be in 'Append' mode, tacking on each attached piece of data
|
||||
// to the end of the list.
|
||||
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tAttach(): too many attachments\n");
|
||||
#endif
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if(size==0)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tAttach(): size invalid -> size=0\n");
|
||||
#endif
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if(bufferlength+size>capacity)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tAttach(): bufferlength+size > port capacity\n");
|
||||
#endif
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// create a new storage object and stash the data
|
||||
PortLinkData *pld=new PortLinkData;
|
||||
if(pld->Set(data,size))
|
||||
if(pld->Set(data,size)==B_OK)
|
||||
{
|
||||
num_attachments++;
|
||||
attachments[num_attachments-1]=pld;
|
||||
bufferlength+=size;
|
||||
#ifdef PLDEBUG
|
||||
printf("\tAttach(): successful\n");
|
||||
printf("\t\tAttach(): attachments now %u\n", num_attachments);
|
||||
printf("\t\tAttach(): buffer length is %lu\n", bufferlength);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("\tAttach(): Couldn't assign data to PortLinkData object\n");
|
||||
#endif
|
||||
delete pld;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -333,6 +425,9 @@ status_t PortLink::Attach(void *data, size_t size)
|
||||
|
||||
status_t PortLink::Attach(int32 data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%ld)\n",data);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -359,6 +454,9 @@ status_t PortLink::Attach(int32 data)
|
||||
|
||||
status_t PortLink::Attach(int16 data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%d)\n",data);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -385,6 +483,9 @@ status_t PortLink::Attach(int16 data)
|
||||
|
||||
status_t PortLink::Attach(int8 data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%d)\n",data);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -411,6 +512,9 @@ status_t PortLink::Attach(int8 data)
|
||||
|
||||
status_t PortLink::Attach(float data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%f)\n",data);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -437,6 +541,9 @@ status_t PortLink::Attach(float data)
|
||||
|
||||
status_t PortLink::Attach(bool data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(%s)\n",(data)?"true":"false");
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -463,6 +570,9 @@ status_t PortLink::Attach(bool data)
|
||||
|
||||
status_t PortLink::Attach(BRect data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(BRect(%f,%f,%f,%f))\n",data.left,data.top,data.right,data.bottom);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -489,6 +599,9 @@ status_t PortLink::Attach(BRect data)
|
||||
|
||||
status_t PortLink::Attach(BPoint data)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("Attach(BPoint(%f,%f))\n",data.x,data.y);
|
||||
#endif
|
||||
// Prevent parameter problems
|
||||
if(num_attachments>=_PORTLINK_MAX_ATTACHMENTS)
|
||||
return B_ERROR;
|
||||
@@ -521,7 +634,12 @@ void PortLink::FlattenData(int8 **buffer,int32 *size)
|
||||
|
||||
// skip if there aree no attachments
|
||||
if(bufferlength<1)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::FlattenData: bufferlength<1\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
*buffer=new int8[bufferlength];
|
||||
int8 *bufferindex=*buffer;
|
||||
@@ -539,6 +657,9 @@ void PortLink::FlattenData(int8 **buffer,int32 *size)
|
||||
|
||||
void PortLink::MakeEmpty(void)
|
||||
{
|
||||
#ifdef PLDEBUG
|
||||
printf("PortLink::MakeEmpty\n");
|
||||
#endif
|
||||
// Nukes all the attachments currently held by the PortLink class
|
||||
if(num_attachments!=0)
|
||||
{
|
||||
@@ -567,15 +688,36 @@ PortLinkData::~PortLinkData(void)
|
||||
|
||||
status_t PortLinkData::Set(void *data, size_t size)
|
||||
{
|
||||
#ifdef PLD_DEBUG
|
||||
printf("PortLinkData::Set(%p,%lu)\n",data,size);
|
||||
#endif
|
||||
// Function copies the passed to the internal buffers for storage
|
||||
if(size>0 && buffersize==0 && data!=NULL)
|
||||
{
|
||||
buffer=(char *)malloc(size);
|
||||
if(buffer==NULL)
|
||||
if(!buffer)
|
||||
{
|
||||
#ifdef PLD_DEBUG
|
||||
printf("\tSet(): Couldn't allocate buffer\n");
|
||||
#endif
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
memcpy(buffer, data, size);
|
||||
buffersize=size;
|
||||
#ifdef PLD_DEBUG
|
||||
printf("\tSet(): SUCCESS\n");
|
||||
#endif
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
#ifdef PLD_DEBUG
|
||||
if(size==0)
|
||||
printf("\tSet(): given an invalid size\n");
|
||||
if(buffersize>0)
|
||||
printf("\tSet(): buffersize is nonzero\n");
|
||||
if(buffersize>0)
|
||||
printf("\tSet(): data is NULL\n");
|
||||
#endif
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user