From 51c9c2f980ddaae9c3eb4626910a143659dfd32e Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Tue, 19 Nov 2002 00:30:49 +0000 Subject: [PATCH] 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 --- src/kits/app/PortLink.cpp | 158 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 8 deletions(-) diff --git a/src/kits/app/PortLink.cpp b/src/kits/app/PortLink.cpp index a3c3904aea..e41ecb51aa 100644 --- a/src/kits/app/PortLink.cpp +++ b/src/kits/app/PortLink.cpp @@ -28,6 +28,15 @@ capacity - contains the storage capacity of the target port. #include //#define PLDEBUG +//#define PLD_DEBUG + +#ifdef PLDEBUG +#include +#endif + +#ifdef PLD_DEBUG +#include +#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; }