extended NORM_SEND_ERROR notification and added info-only (0 size files, etc) object support

pull/9/head
bebopagogo 2020-03-01 12:21:58 -05:00
parent b413447f6b
commit e9469280c1
7 changed files with 163 additions and 216 deletions

View File

@ -1051,10 +1051,9 @@ int main(int argc, char* argv[])
{ {
fprintf(stderr, "normMsgr error: unable to open NORM session\n"); fprintf(stderr, "normMsgr error: unable to open NORM session\n");
NormDestroyInstance(normInstance); NormDestroyInstance(normInstance);
return false; return -1;
} }
if (silentReceiver) normMsgr.SetSilentReceiver(true); if (silentReceiver) normMsgr.SetSilentReceiver(true);
if (txloss > 0.0) normMsgr.SetTxLoss(txloss); if (txloss > 0.0) normMsgr.SetTxLoss(txloss);

View File

@ -57,7 +57,9 @@ class NormController
CC_INACTIVE, // posted when no cc feedback and min rate reached CC_INACTIVE, // posted when no cc feedback and min rate reached
ACKING_NODE_NEW, ACKING_NODE_NEW,
SEND_ERROR, SEND_ERROR,
USER_TIMEOUT USER_TIMEOUT,
// The ones below here are not exposed via the NORM API
SEND_OK,
}; };
virtual void Notify(NormController::Event event, virtual void Notify(NormController::Event event,
@ -267,6 +269,9 @@ class NormSession
} }
void SetTxRateBounds(double rateMin, double rateMax); void SetTxRateBounds(double rateMin, double rateMax);
void ClearSendError()
{posted_send_error = false;}
double BackoffFactor() double BackoffFactor()
{return backoff_factor;} {return backoff_factor;}
void SetBackoffFactor(double value) void SetBackoffFactor(double value)
@ -778,6 +783,7 @@ class NormSession
int flush_count; int flush_count;
bool posted_tx_queue_empty; bool posted_tx_queue_empty;
bool posted_tx_rate_changed; bool posted_tx_rate_changed;
bool posted_send_error;
// For postive acknowledgement collection // For postive acknowledgement collection
NormNodeTree acking_node_tree; NormNodeTree acking_node_tree;

View File

@ -116,51 +116,12 @@ class NormInstance : public NormController
return static_cast<NormInstance*>(session.GetSessionMgr().GetController()); return static_cast<NormInstance*>(session.GetSessionMgr().GetController());
} }
class Notification class Notification : public ProtoList::Item
{ {
public: public:
NormEvent event; NormEvent event;
void Append(Notification* n) {next = n;} class Queue : public ProtoListTemplate<Notification> {};
Notification* GetNext() const {return next;}
class Queue
{
public:
Queue();
~Queue();
bool IsEmpty() const {return (NULL == head);}
void Destroy();
void Append(Notification* n)
{
n->Append(NULL);
if (tail)
tail->Append(n);
else
head = n;
tail = n;
}
Notification* RemoveHead()
{
Notification* n = head;
if (n)
{
head = n->GetNext();
tail = head ? tail : NULL;
}
return n;
}
Notification* GetHead() {return head;}
void SetTail(Notification* n) {tail = n;}
private:
Notification* head;
Notification* tail;
}; // end class NormInstance::Notification::Queue
private:
Notification* next;
}; // end class NormInstance::Notification }; // end class NormInstance::Notification
ProtoDispatcher dispatcher; ProtoDispatcher dispatcher;
@ -193,25 +154,6 @@ class NormInstance : public NormController
#endif // if/else WIN32/UNIX #endif // if/else WIN32/UNIX
}; // end class NormInstance }; // end class NormInstance
////////////////////////////////////////////////////
// NormInstance::Notification::Queue implementation
NormInstance::Notification::Queue::Queue()
: head(NULL), tail(NULL)
{
}
NormInstance::Notification::Queue::~Queue()
{
Destroy();
}
void NormInstance::Notification::Queue::Destroy()
{
Notification* n;
while ((n = RemoveHead())) delete n;
} // end NormInstance::Notification::Queue::Destroy()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// NormInstance implementation // NormInstance implementation
@ -274,17 +216,26 @@ void NormInstance::Notify(NormController::Event event,
class NormNode* node, class NormNode* node,
class NormObject* object) class NormObject* object)
{ {
switch (event)
{
case SEND_OK:
// Purge any pending NORM_SEND_ERROR notifications for session
PurgeNotifications(session, NORM_SEND_ERROR);
return;
default:
break;
}
// (TBD) set a limit on how many pending notifications // (TBD) set a limit on how many pending notifications
// we allow to queue up (it could be large and probably // we allow to queue up (it could be large and probably
// we could base it on how much memory space the pending // we could base it on how much memory space the pending
// notifications are allowed to consume. // notifications are allowed to consume.
Notification* n = notify_pool.RemoveHead(); Notification* next = notify_pool.RemoveHead();
if (!n) if (NULL == next)
{ {
if (!(n = new Notification)) if (NULL == (next = new Notification))
{ {
PLOG(PL_FATAL, "NormInstance::Notify() new Notification error: %s\n", PLOG(PL_FATAL, "NormInstance::Notify() new Notification error: %s\n", GetErrorString());
GetErrorString());
return; return;
} }
} }
@ -306,7 +257,7 @@ void NormInstance::Notify(NormController::Event event,
if (!stream->Accept(size.LSB(), true)) if (!stream->Accept(size.LSB(), true))
{ {
PLOG(PL_FATAL, "NormInstance::Notify() stream accept error\n"); PLOG(PL_FATAL, "NormInstance::Notify() stream accept error\n");
notify_pool.Append(n); notify_pool.Append(*next);
return; return;
} }
// By setting a non-zero "block pool threshold", this // By setting a non-zero "block pool threshold", this
@ -375,6 +326,7 @@ void NormInstance::Notify(NormController::Event event,
{ {
// we're ignoring files // we're ignoring files
PLOG(PL_DETAIL, "NormInstance::Notify() warning: receive file but no cache directory set, so ignoring file\n"); PLOG(PL_DETAIL, "NormInstance::Notify() warning: receive file but no cache directory set, so ignoring file\n");
notify_pool.Append(*next);
return; return;
} }
break; break;
@ -387,7 +339,8 @@ void NormInstance::Notify(NormController::Event event,
if (NULL == dataPtr) if (NULL == dataPtr)
{ {
PLOG(PL_FATAL, "NormInstance::Notify(RX_OBJECT_NEW) new dataPtr error: %s\n", PLOG(PL_FATAL, "NormInstance::Notify(RX_OBJECT_NEW) new dataPtr error: %s\n",
GetErrorString()); GetErrorString());
notify_pool.Append(*next);
return; return;
} }
// Note that the "true" parameter means the // Note that the "true" parameter means the
@ -395,11 +348,17 @@ void NormInstance::Notify(NormController::Event event,
// data on object deletion, so the app should // data on object deletion, so the app should
// use NormDataDetachData() to keep the received // use NormDataDetachData() to keep the received
// data (or copy it before the data object is deleted) // data (or copy it before the data object is deleted)
dataObj->Accept(dataPtr, dataLen, true); if (!dataObj->Accept(dataPtr, dataLen, true))
{
PLOG(PL_FATAL, "NormInstance::Notify() data object accept error\n");
notify_pool.Append(*next);
return;
}
break; break;
} }
default: default:
// This shouldn't occur // This shouldn't occur
notify_pool.Append(*next);
return; return;
} // end switch(object->GetType()) } // end switch(object->GetType())
break; break;
@ -416,11 +375,11 @@ void NormInstance::Notify(NormController::Event event,
((NormNode*)node)->Retain(); ((NormNode*)node)->Retain();
bool doNotify = notify_queue.IsEmpty(); bool doNotify = notify_queue.IsEmpty();
n->event.type = (NormEventType)event; next->event.type = (NormEventType)event;
n->event.session = session; next->event.session = session;
n->event.sender = node; next->event.sender = node;
n->event.object = object; next->event.object = object;
notify_queue.Append(n); notify_queue.Append(*next);
if (doNotify) if (doNotify)
{ {
@ -428,7 +387,7 @@ void NormInstance::Notify(NormController::Event event,
if (0 == SetEvent(notify_event)) if (0 == SetEvent(notify_event))
{ {
PLOG(PL_ERROR, "NormInstance::Notify() SetEvent() error: %s\n", PLOG(PL_ERROR, "NormInstance::Notify() SetEvent() error: %s\n",
GetErrorString()); GetErrorString());
} }
#else #else
char byte = 0; char byte = 0;
@ -437,7 +396,7 @@ void NormInstance::Notify(NormController::Event event,
if ((EINTR != errno) && (EAGAIN != errno)) if ((EINTR != errno) && (EAGAIN != errno))
{ {
PLOG(PL_FATAL, "NormInstance::Notify() write() error: %s\n", PLOG(PL_FATAL, "NormInstance::Notify() write() error: %s\n",
GetErrorString()); GetErrorString());
break; break;
} }
} }
@ -449,35 +408,25 @@ void NormInstance::Notify(NormController::Event event,
void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle) void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle)
{ {
if (NORM_OBJECT_INVALID == objectHandle) return; if (NORM_OBJECT_INVALID == objectHandle) return;
Notification* prev = NULL;
Notification* next = notify_queue.GetHead(); Notification::Queue::Iterator iterator(notify_queue);
while (next) Notification* next;
while (NULL != (next = iterator.GetNextItem()))
{ {
if (objectHandle == next->event.object) if (objectHandle == next->event.object)
{ {
// "Release" the previously-retained object handle // "Release" the previously-retained object handle
((NormObject*)objectHandle)->Release(); ((NormObject*)objectHandle)->Release();
// Remove this notification from queue and return to pool // Remove from queue and put in pool
Notification* current = next; notify_queue.Remove(*next);
next = next->GetNext(); notify_pool.Append(*next);
if (NULL != prev)
prev->Append(next);
else
notify_queue.RemoveHead();
if (NULL == next) notify_queue.SetTail(prev);
notify_pool.Append(current);
}
else
{
prev = next;
next = next->GetNext();
} }
} }
if ((NULL != previous_notification) && (objectHandle == previous_notification->event.object)) if ((NULL != previous_notification) && (objectHandle == previous_notification->event.object))
{ {
// "Release" any previously-retained object or node handle // "Release" any previously-retained object or node handle
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
// TBD - check if event queue is emptied and reset event/fd // TBD - check if event queue is emptied and reset event/fd
@ -487,28 +436,17 @@ void NormInstance::PurgeObjectNotifications(NormObjectHandle objectHandle)
void NormInstance::PurgeNodeNotifications(NormNodeHandle nodeHandle) void NormInstance::PurgeNodeNotifications(NormNodeHandle nodeHandle)
{ {
if (NORM_NODE_INVALID == nodeHandle) return; if (NORM_NODE_INVALID == nodeHandle) return;
Notification* prev = NULL; Notification::Queue::Iterator iterator(notify_queue);
Notification* next = notify_queue.GetHead(); Notification* next;
while (next) while (NULL != (next = iterator.GetNextItem()))
{ {
if (nodeHandle == next->event.sender) if (nodeHandle == next->event.sender)
{ {
// "Release" the previously-retained object handle // "Release" the previously-retained object handle
((NormNode*)nodeHandle)->Release(); ((NormNode*)nodeHandle)->Release();
// Remove this notification from queue and return to pool // Remove this notification from queue and return to pool
Notification* current = next; notify_queue.Remove(*next);
next = next->GetNext(); notify_pool.Append(*next);
if (NULL != prev)
prev->Append(next);
else
notify_queue.RemoveHead();
if (NULL == next) notify_queue.SetTail(prev);
notify_pool.Append(current);
}
else
{
prev = next;
next = next->GetNext();
} }
} }
if ((NULL != previous_notification) && (nodeHandle == previous_notification->event.sender)) if ((NULL != previous_notification) && (nodeHandle == previous_notification->event.sender))
@ -518,7 +456,7 @@ void NormInstance::PurgeNodeNotifications(NormNodeHandle nodeHandle)
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
else else
((NormNode*)(previous_notification->event.sender))->Release(); ((NormNode*)(previous_notification->event.sender))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
if (notify_queue.IsEmpty()) ResetNotificationEvent(); if (notify_queue.IsEmpty()) ResetNotificationEvent();
@ -527,31 +465,20 @@ void NormInstance::PurgeNodeNotifications(NormNodeHandle nodeHandle)
void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle) void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
{ {
if (NORM_SESSION_INVALID == sessionHandle) return; if (NORM_SESSION_INVALID == sessionHandle) return;
Notification* prev = NULL; Notification::Queue::Iterator iterator(notify_queue);
Notification* next = notify_queue.GetHead(); Notification* next;
while (NULL != next) while (NULL != (next = iterator.GetNextItem()))
{ {
if (next->event.session == sessionHandle) if (next->event.session == sessionHandle)
{ {
if (NORM_OBJECT_INVALID != next->event.object)
((NormObject*)next->event.object)->Release();
else if (NORM_NODE_INVALID != next->event.sender)
((NormNode*)next->event.sender)->Release();
// Remove this notification from queue and return to pool // Remove this notification from queue and return to pool
Notification* current = next; notify_queue.Remove(*next);
next = next->GetNext(); notify_pool.Append(*next);
if (NULL != prev) }
prev->Append(next);
else
notify_queue.RemoveHead();
if (NULL == next) notify_queue.SetTail(prev);
if (NORM_OBJECT_INVALID != current->event.object)
((NormObject*)current->event.object)->Release();
else if (NORM_NODE_INVALID != current->event.sender)
((NormNode*)current->event.sender)->Release();
notify_pool.Append(current);
}
else
{
prev = next;
next = next->GetNext();
}
} }
if ((NULL != previous_notification) && (sessionHandle == previous_notification->event.session)) if ((NULL != previous_notification) && (sessionHandle == previous_notification->event.session))
{ {
@ -560,7 +487,7 @@ void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
else if (NORM_NODE_INVALID != previous_notification->event.sender) else if (NORM_NODE_INVALID != previous_notification->event.sender)
((NormNode*)(previous_notification->event.sender))->Release(); ((NormNode*)(previous_notification->event.sender))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
if (notify_queue.IsEmpty()) ResetNotificationEvent(); if (notify_queue.IsEmpty()) ResetNotificationEvent();
@ -570,32 +497,21 @@ void NormInstance::PurgeSessionNotifications(NormSessionHandle sessionHandle)
void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType) void NormInstance::PurgeNotifications(NormSessionHandle sessionHandle, NormEventType eventType)
{ {
if (NORM_SESSION_INVALID == sessionHandle) return; if (NORM_SESSION_INVALID == sessionHandle) return;
Notification* prev = NULL; Notification::Queue::Iterator iterator(notify_queue);
Notification* next = notify_queue.GetHead(); Notification* next;
while (next) while (NULL != (next = iterator.GetNextItem()))
{ {
if ((next->event.session == sessionHandle) && if ((next->event.session == sessionHandle) &&
(next->event.type == eventType)) (next->event.type == eventType))
{ {
if (NORM_OBJECT_INVALID != next->event.object)
((NormObject*)next->event.object)->Release();
else if (NORM_NODE_INVALID != next->event.sender)
((NormNode*)next->event.sender)->Release();
// Remove this notification from queue and return to pool // Remove this notification from queue and return to pool
Notification* current = next; notify_queue.Remove(*next);
next = next->GetNext(); notify_pool.Append(*next);
if (NULL != prev)
prev->Append(next);
else
notify_queue.RemoveHead();
if (NULL == next) notify_queue.SetTail(prev);
if (NORM_OBJECT_INVALID != current->event.object)
((NormObject*)current->event.object)->Release();
else if (NORM_NODE_INVALID != current->event.sender)
((NormNode*)current->event.sender)->Release();
notify_pool.Append(current);
} }
else
{
prev = next;
next = next->GetNext();
}
} }
if (notify_queue.IsEmpty()) ResetNotificationEvent(); if (notify_queue.IsEmpty()) ResetNotificationEvent();
} // end NormInstance::PurgeNotifications() } // end NormInstance::PurgeNotifications()
@ -611,19 +527,19 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
else if (NORM_NODE_INVALID != previous_notification->event.sender) else if (NORM_NODE_INVALID != previous_notification->event.sender)
((NormNode*)(previous_notification->event.sender))->Release(); ((NormNode*)(previous_notification->event.sender))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
Notification* n; Notification* next;
while (NULL != (n = notify_queue.RemoveHead())) while (NULL != (next = notify_queue.RemoveHead()))
{ {
switch (n->event.type) switch (next->event.type)
{ {
case NORM_EVENT_INVALID: case NORM_EVENT_INVALID:
if (!notify_queue.IsEmpty()) if (!notify_queue.IsEmpty())
{ {
// Discard this invalid event and get next one // Discard this invalid event and get next one
notify_pool.Append(n); notify_pool.Append(*next);
continue; continue;
} }
break; break;
@ -631,20 +547,25 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
{ {
// reset update event notification for non-streams // reset update event notification for non-streams
// (NormStreamRead() takes care of streams) // (NormStreamRead() takes care of streams)
NormObject* obj = ((NormObject*)n->event.object); NormObject* obj = ((NormObject*)next->event.object);
if (!obj->IsStream()) if (!obj->IsStream()) obj->SetNotifyOnUpdate(true);
obj->SetNotifyOnUpdate(true); break;
}
case NORM_SEND_ERROR:
{
NormSession* session = (NormSession*)next->event.session;
session->ClearSendError();
break; break;
} }
default: default:
break; break;
} }
break; break;
} }
if (NULL != n) if (NULL != next)
{ {
previous_notification = n; // keep dispatched event for garbage collection previous_notification = next; // keep dispatched event for garbage collection
if (NULL != theEvent) *theEvent = n->event; if (NULL != theEvent) *theEvent = next->event;
} }
else if (NULL != theEvent) else if (NULL != theEvent)
{ {
@ -653,9 +574,8 @@ bool NormInstance::GetNextEvent(NormEvent* theEvent)
theEvent->sender = NORM_NODE_INVALID; theEvent->sender = NORM_NODE_INVALID;
theEvent->object = NORM_OBJECT_INVALID; theEvent->object = NORM_OBJECT_INVALID;
} }
if (notify_queue.IsEmpty()) if (notify_queue.IsEmpty()) ResetNotificationEvent();
ResetNotificationEvent(); return (NULL != next);
return (NULL != n);
} // end NormInstance::GetNextEvent() } // end NormInstance::GetNextEvent()
bool NormInstance::WaitForEvent() bool NormInstance::WaitForEvent()
@ -737,7 +657,7 @@ void NormInstance::ReleasePreviousEvent()
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
else if (NORM_NODE_INVALID != previous_notification->event.sender) else if (NORM_NODE_INVALID != previous_notification->event.sender)
((NormNode*)(previous_notification->event.sender))->Release(); ((NormNode*)(previous_notification->event.sender))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
} // end NormInstance::ReleasePreviousEvent() } // end NormInstance::ReleasePreviousEvent()
@ -785,18 +705,18 @@ void NormInstance::Shutdown()
((NormObject*)(previous_notification->event.object))->Release(); ((NormObject*)(previous_notification->event.object))->Release();
else if (NORM_NODE_INVALID != previous_notification->event.sender) else if (NORM_NODE_INVALID != previous_notification->event.sender)
((NormNode*)(previous_notification->event.sender))->Release(); ((NormNode*)(previous_notification->event.sender))->Release();
notify_pool.Append(previous_notification); notify_pool.Append(*previous_notification);
previous_notification = NULL; previous_notification = NULL;
} }
Notification* n; Notification* next;
while ((n = notify_queue.RemoveHead())) while (NULL != (next = notify_queue.RemoveHead()))
{ {
switch (n->event.type) switch (next->event.type)
{ {
case NORM_RX_OBJECT_NEW: case NORM_RX_OBJECT_NEW:
{ {
NormObject* obj = (NormObject*)n->event.object; NormObject* obj = (NormObject*)next->event.object;
switch (obj->GetType()) switch (obj->GetType())
{ {
case NormObject::FILE: case NormObject::FILE:
@ -810,30 +730,33 @@ void NormInstance::Shutdown()
default: default:
break; break;
} }
if (NORM_OBJECT_INVALID != n->event.object) if (NORM_OBJECT_INVALID != next->event.object)
((NormObject*)(n->event.object))->Release(); ((NormObject*)(next->event.object))->Release();
else if (NORM_NODE_INVALID != n->event.sender) else if (NORM_NODE_INVALID != next->event.sender)
((NormNode*)(n->event.sender))->Release(); ((NormNode*)(next->event.sender))->Release();
delete n; delete next;
} }
notify_pool.Destroy(); notify_pool.Destroy();
} // end NormInstance::Shutdown() } // end NormInstance::Shutdown()
/*
This function doesn't make sense?
UINT32 NormInstance::CountCompletedObjects(NormSession* session) UINT32 NormInstance::CountCompletedObjects(NormSession* session)
{ {
UINT32 result = 0UL; UINT32 result = 0UL;
Notification* n = notify_queue.GetHead(); Notification::Queue::Iterator iterator(notify_queue);
while (NULL != n) Notification* next;
while (NULL != (next = iterator.GetNextItem()))
{ {
if ((session == n->event.session) && if ((session == next->event.session) &&
(NORM_RX_OBJECT_COMPLETED == n->event.type)) (NORM_RX_OBJECT_COMPLETED == next->event.type))
{ {
result ++; result ++;
} }
n = n->GetNext();
} }
return result; return result;
} // end NormInstance::CountCompletedObjects() } // end NormInstance::CountCompletedObjects()
*/
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// NORM API FUNCTION IMPLEMENTATIONS // NORM API FUNCTION IMPLEMENTATIONS
@ -3051,7 +2974,7 @@ void NormNodeRelease(NormNodeHandle nodeHandle)
// is done so that this current approach is not very costly) // is done so that this current approach is not very costly)
// //
/*
// Not sure why this function exists. It just counts the number // Not sure why this function exists. It just counts the number
// of RX_OBJECT_COMPLETED events currently in notification queue // of RX_OBJECT_COMPLETED events currently in notification queue
// which is a temporary and transitory thing??? // which is a temporary and transitory thing???
@ -3068,3 +2991,4 @@ UINT32 NormCountCompletedObjects(NormSessionHandle sessionHandle)
} }
return result; return result;
} // end NormCountCompletedObjects() } // end NormCountCompletedObjects()
*/

View File

@ -201,7 +201,9 @@ bool NormObject::Open(const NormObjectSize& objectSize,
pending_mask.SetBits(0, numBlocks.LSB()); pending_mask.SetBits(0, numBlocks.LSB());
// Compute FEC block structure per NORM Protocol Spec Section 5.1.1 // Compute FEC block structure per NORM Protocol Spec Section 5.1.1
// (Note NormObjectSize divide operator always rounds _up_, i.e., ceil(numSegments/numBlocks)) // (Note NormObjectSize divide operator always rounds _up_, i.e., ceil(numSegments/numBlocks))
NormObjectSize largeBlockSize = numSegments / numBlocks; NormObjectSize largeBlockSize;
if ((0 != numBlocks.MSB()) || (0 != numBlocks.LSB()))
largeBlockSize = numSegments / numBlocks;
ASSERT(0 == largeBlockSize.MSB()); ASSERT(0 == largeBlockSize.MSB());
large_block_size = largeBlockSize.LSB(); large_block_size = largeBlockSize.LSB();
if (numSegments == (numBlocks*largeBlockSize)) if (numSegments == (numBlocks*largeBlockSize))
@ -2336,7 +2338,7 @@ bool NormFileObject::Open(const char* thePath,
if (file.Open(thePath, O_RDONLY)) if (file.Open(thePath, O_RDONLY))
{ {
NormObjectSize::Offset size = file.GetSize(); NormObjectSize::Offset size = file.GetSize();
if (size) //if (size)
{ {
if (!NormObject::Open(NormObjectSize(size), if (!NormObject::Open(NormObjectSize(size),
infoPtr, infoPtr,
@ -2352,12 +2354,13 @@ bool NormFileObject::Open(const char* thePath,
return false; return false;
} }
} }
/*
else else
{ {
PLOG(PL_FATAL, "NormFileObject::Open() send file.GetSize() error!\n"); PLOG(PL_FATAL, "NormFileObject::Open() send file.GetSize() error!\n");
file.Close(); file.Close();
return false; return false;
} }*/
} }
else else
{ {

View File

@ -701,7 +701,8 @@ bool NormBlockBuffer::Init(unsigned long rangeMax, unsigned long tableSize, UINT
{ {
Destroy(); Destroy();
// Make sure tableSize is greater than 0 and 2^n // Make sure tableSize is greater than 0 and 2^n
if (!rangeMax || !tableSize) //if (!rangeMax || !tableSize)
if (0 == tableSize)
{ {
PLOG(PL_FATAL, "NormBlockBuffer::Init() bad range(%lu) or tableSize(%lu)\n", PLOG(PL_FATAL, "NormBlockBuffer::Init() bad range(%lu) or tableSize(%lu)\n",
rangeMax, tableSize); rangeMax, tableSize);

View File

@ -53,7 +53,7 @@ NormSession::NormSession(NormSessionMgr& sessionMgr, NormNodeId localNodeId)
tx_cache_count_min(DEFAULT_TX_CACHE_MIN), tx_cache_count_min(DEFAULT_TX_CACHE_MIN),
tx_cache_count_max(DEFAULT_TX_CACHE_MAX), tx_cache_count_max(DEFAULT_TX_CACHE_MAX),
tx_cache_size_max(DEFAULT_TX_CACHE_SIZE), tx_cache_size_max(DEFAULT_TX_CACHE_SIZE),
posted_tx_queue_empty(false), posted_tx_rate_changed(false), posted_tx_queue_empty(false), posted_tx_rate_changed(false), posted_send_error(false),
acking_node_count(0), acking_auto_populate(TRACK_NONE), watermark_pending(false), watermark_flushes(false), acking_node_count(0), acking_auto_populate(TRACK_NONE), watermark_pending(false), watermark_flushes(false),
tx_repair_pending(false), advertise_repairs(false), tx_repair_pending(false), advertise_repairs(false),
suppress_nonconfirmed(false), suppress_rate(-1.0), suppress_rtt(-1.0), suppress_nonconfirmed(false), suppress_rate(-1.0), suppress_rtt(-1.0),
@ -4907,40 +4907,54 @@ NormSession::MessageStatus NormSession::SendMessage(NormMsg& msg)
{ {
unsigned int numBytes = msgSize; unsigned int numBytes = msgSize;
bool result = tx_socket->SendTo(msg.GetBuffer(), numBytes, msg.GetDestination()); bool result = tx_socket->SendTo(msg.GetBuffer(), numBytes, msg.GetDestination());
if (numBytes == msgSize)
if (result)
{ {
// Separate send/recv tracing if (numBytes == msgSize)
if (trace)
{ {
struct timeval currentTime; if (posted_send_error)
ProtoSystemTime(currentTime); {
NormTrace(currentTime, LocalNodeId(), msg, true, fecM, instId); // Clear SEND_ERROR indication
posted_send_error = false;
Notify(NormController::SEND_OK, NULL, NULL);
}
// Separate send/recv tracing
if (trace)
{
struct timeval currentTime;
ProtoSystemTime(currentTime);
NormTrace(currentTime, LocalNodeId(), msg, true, fecM, instId);
}
// To keep track of _actual_ sent rate
sent_accumulator.Increment(msgSize);
// Update nominal packet size
nominal_packet_size += 0.01 * (((double)msgSize) - nominal_packet_size);
}
else
{
// packet not sent
tx_sequence--;
// TBD - is PL_WARN too verbose here
PLOG(PL_WARN, "NormSession::SendMessage() sendto(%s/%hu) 'blocked' warning: %s\n",
msg.GetDestination().GetHostString(), msg.GetDestination().GetPort(), GetErrorString());
return MSG_SEND_BLOCKED;
} }
// To keep track of _actual_ sent rate
sent_accumulator.Increment(msgSize);
// Update nominal packet size
nominal_packet_size += 0.01 * (((double)msgSize) - nominal_packet_size);
} }
else else
{ {
// packet not sent // packet not sent
tx_sequence--; tx_sequence--;
if (result) PLOG(PL_WARN, "NormSession::SendMessage() sendto(%s/%hu) 'failed' warning: %s\n",
msg.GetDestination().GetHostString(), msg.GetDestination().GetPort(), GetErrorString());
if (!posted_send_error)
{ {
// TBD - is PL_WARN too verbose here // Post a Notify(NormController::SEND_ERROR, NULL, NULL);
PLOG(PL_WARN, "NormSession::SendMessage() sendto(%s/%hu) warning: %s\n", posted_send_error = true;
msg.GetDestination().GetHostString(), msg.GetDestination().GetPort(), GetErrorString()); Notify(NormController::SEND_ERROR, NULL, NULL);
return MSG_SEND_BLOCKED;
}
else
{
PLOG(PL_WARN, "NormSession::SendMessage() sendto(%s/%hu) warning: %s\n",
msg.GetDestination().GetHostString(), msg.GetDestination().GetPort(), GetErrorString());
return MSG_SEND_FAILED;
} }
return MSG_SEND_FAILED;
} }
} }
if (isProbe) if (isProbe)
{ {
probe_pending = false; probe_pending = false;

View File

@ -5,7 +5,7 @@ package mil.navy.nrl.norm.enums;
* the native implementation and therefore is tied to the specific version of * the native implementation and therefore is tied to the specific version of
* NORM. * NORM.
* *
* @author Jason Rush * @author Jason Rush and Brian Adamson
*/ */
public enum NormEventType { public enum NormEventType {
NORM_EVENT_INVALID, NORM_EVENT_INVALID,