void nw_receiveChannelRead( nw_receiveChannel receiveChannel, v_message *messagePtr, v_networkReaderEntry *entryPtr, const nw_entryLookupAction entryLookupAction, nw_entryLookupArg entryLookupArg, plugReceiveStatistics prs) { nw_channel channel = (nw_channel)receiveChannel; NW_STRUCT(nw_lookupArg) lookupArg; NW_CONFIDENCE(channel != NULL); lookupArg.receiveChannel = receiveChannel; lookupArg.entryLookupAction = entryLookupAction; lookupArg.entryLookupArg = entryLookupArg; lookupArg.entryFound = NULL; nw_bridgeRead(channel->owningBridge, channel->channelId, messagePtr, onTypeLookup, &lookupArg, prs); if (*messagePtr == NULL) { /* If message has been dropped (NULL) for security reasons, * the entry still might be non-NULL, correct this */ lookupArg.entryFound = NULL; } /* Retrieve entry, but only if we still have the previous message */ if (*entryPtr == NULL) { *entryPtr = lookupArg.entryFound; } }
static void nw_plugInterCommRequestMessageNew( nw_ringBufferEntry ringBufEntries[], os_uint32 nofEntries ) { nw_plugInterCommRequestMessage array; os_uint32 i; array = os_malloc(sizeof(NW_STRUCT(nw_plugInterCommRequestMessage)) * nofEntries); if (array) { for (i=0; i<nofEntries; i++) { ringBufEntries[i] = (nw_ringBufferEntry)&array[i]; } } }
static void nw_channelWriterMain( v_entity e, c_voidp arg) { v_networkReader reader; nw_channelWriter channelWriter; c_bool newGroupAvailable; v_networkQueue qosQueue; v_networkReaderWaitResult waitResult; c_long bytesWritten; /* Total number of messages sent to the network */ c_ulong writtenCountMessages; /* Total number of bytes sent to the network */ c_ulong writtenCountBytes; /* Total number of bytes sent to the network during one burst */ c_ulong writtenCountBytesThisBurst; /* Number of message sent to the network after last report */ c_ulong writtenCountMessagesReport; v_message message; v_networkReaderEntry entry; c_ulong sequenceNumber; v_gid sender; c_bool sendTo; v_gid receiver; c_time sendBefore; c_ulong priority; c_bool more = TRUE; c_bool slowingDown; c_ulong timeoutCount; nw_signedLength credits; v_networking n; NW_STRUCT(plugSendStatistics) pss = {0,0,0,0,0,0,0,0,0,0, {0, {{0,0}, 0}, {{0,0}, 0}, {0.0,0}}, {0, {{0,0}, 0}, {{0,0}, 0}, {0.0,0}}, 0,0,0}; v_fullCounterInit(&(pss.adminQueueAcks)); v_fullCounterInit(&(pss.adminQueueData)); reader = v_networkReader(e); channelWriter = (nw_channelWriter)arg; /* This line is needed as long as the discovery channel is not yet implemented */ writtenCountBytesThisBurst = 0; writtenCountMessages = 0; writtenCountBytes = 0; writtenCountMessagesReport = 0; slowingDown = FALSE; timeoutCount = 0; credits = 0; while (!(int)nw_runnableTerminationRequested((nw_runnable)channelWriter)) { /* Wait for data on the reader */ if (!slowingDown) { waitResult = v_networkReaderWait(reader, channelWriter->queueId, &qosQueue); } else { waitResult = v_networkReaderWaitDelayed(reader, channelWriter->queueId, &qosQueue); NW_CONFIDENCE(waitResult & (V_WAITRESULT_TIMEOUT | V_WAITRESULT_TRIGGERED)); } if ((waitResult & V_WAITRESULT_TRIGGERED) && (!nw_runnableTerminationRequested((nw_runnable)channelWriter))) { /* If necessary, check if any new groups need to be added */ newGroupAvailable = nw_channelUserRetrieveNewGroup( (nw_channelUser)channelWriter, &entry); while (newGroupAvailable) { /* Create a new channel on the network */ /* No, do not call any function. With the new design, * a channelWriter does not need to know anything about this * new group. Maybe at a later stage. */ /* nw_channelAddGroup((nw_channel)channelWriter->sendChannel, entry); */ /* And notify we are connected */ v_networkReaderEntryNotifyConnected(entry,channelWriter->serviceName); newGroupAvailable = nw_channelUserRetrieveNewGroup( (nw_channelUser)channelWriter, &entry); } } /* Resend data should also obey max_burst_size * Each clocktick, the remaining credits of the last period and a * third of the new max_burst_size budget may be used for resend data. * The rest of the budget is assigned after that, and can be used to * flush stored buffers of send fresh data. */ if (waitResult & V_WAITRESULT_TIMEOUT) { /* * The periodic action is needed for every clocktick. * This will also update the credits, for the amount of bandwidth * available in the coming period. */ /*stat update routine */ n = v_networking(v_subscriber(v_reader(reader)->subscriber)->participant); /* update statistics */ if (v_entity(n)->statistics) { if (!pss.enabled) { pss.enabled =1; } /* sync plug stats */ nw_updatePlugSendStatistics(&pss,channelWriter); nw_SendChannelUpdate(v_networkingStatistics(v_entity(n)->statistics)->channels[channelWriter->stat_channel_id],channelWriter->scs); } nw_sendChannelPeriodicAction(channelWriter->sendChannel,&credits,&pss); /*struc call*/ /* A flush is needed if we are slowing down. */ if (slowingDown) { /* The return value is true is all data has been sent. * Afterwards, credits will contain the new amount of allowed * bytes. * We are using a special flush function here that flushes full * buffers only */ slowingDown = !nw_sendChannelFlush(channelWriter->sendChannel, FALSE, &credits, &pss); } } if ((waitResult & V_WAITRESULT_MSGWAITING) && !slowingDown) { /* Messages are waiting... */ writtenCountBytesThisBurst = 0; more= TRUE; while (more && ((nw_signedLength)writtenCountBytesThisBurst <= credits)) { /* Take any new messages */ v_networkQueueTakeFirst(qosQueue, &message, &entry, &sequenceNumber, &sender, &sendTo, &receiver, &sendBefore, &priority, &more); NW_CONFIDENCE(message != NULL); NW_CONFIDENCE(entry != NULL); if (!(NW_SECURITY_CHECK_FOR_PUBLISH_PERMISSION_OF_SENDER_ON_SENDER_SIDE(entry))) { bytesWritten = 0; /* indicates that nothing has been written */ NW_REPORT_WARNING_2( "nw_channelWriterMain", "Channel \"%s\" could not deliver message 0x%x : message dropped!", ((nw_runnable)channelWriter)->name, message); } else { bytesWritten = nw_sendChannelWrite(channelWriter->sendChannel, entry, message, &credits ,&pss); /* stat struc plug vars */ if (bytesWritten == 0) { NW_REPORT_WARNING_2( "nw_channelWriterMain", "Channel \"%s\" could not deliver message 0x%x : message dropped!", ((nw_runnable)channelWriter)->name, message); } /*numberOfMessagesSent stats*/ if (pss.enabled) { channelWriter->scs->numberOfMessagesSent++; } assert( bytesWritten > 0); /* if permission grantedm the value must be greater 0 */ } writtenCountBytesThisBurst += bytesWritten; #define NW_IS_BUILTIN_DOMAINNAME(name) ((int)(name)[0] == (int)'_') /* Do not trace for internal partitions */ if (bytesWritten>0 && /* might be 0 if access control refuses write permission */ !NW_IS_BUILTIN_DOMAINNAME( v_partitionName(v_groupPartition(entry->group)))) { #undef NW_IS_BUILTIN_DOMAINNAME writtenCountBytes += bytesWritten; writtenCountMessages++; writtenCountMessagesReport++; if (writtenCountMessagesReport == channelWriter->reportInterval) { NW_TRACE_3(Send, 3, "Channel %s: %u messages (%u bytes) " "taken from queue and written to network", ((nw_runnable)channelWriter)->name, writtenCountMessages, writtenCountBytes); writtenCountMessagesReport = 0; } NW_TRACE_3(Send, 4, "Channel %s: data message taken from queue, " "and written to network (partition = %s, topic = %s)", ((nw_runnable)channelWriter)->name, v_partitionName(v_groupPartition(entry->group)), v_topicName(v_groupTopic(entry->group))); } c_free(message); c_free(entry); } slowingDown = !nw_sendChannelFlush(channelWriter->sendChannel, TRUE, &credits, &pss); } } NW_TRACE_3(Send, 2, "Channel %s: %u messages (%u bytes) taken from queue and " "written to network", ((nw_runnable)channelWriter)->name, writtenCountMessages, writtenCountBytes); }