extended NORM_SEND_ERROR notification and added info-only (0 size files, etc) object support
parent
b413447f6b
commit
e9469280c1
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue