Pārlūkot izejas kodu

fixing networklayer_tcp select()

fixed socket-overflow on some devices

This is made regarding an embedded device with proprietary
networklayer-functions. It is geared to socket-functions from the
Unix-man page of select(), which says that it only counts the events
which are watched. If no error-event is watched it won't be counted,
which leads to open sockets even if they should be closed because they
were shutdown'd before, because the select isn't triggered because it
doesn't watch for errors, when the parameter for the error-set is NULL.
It now works fine and closes the specific sockets as it should. Sureley
this isn't a noticable problem on big desktop-machines with a lot of
sockets but if you are on an embedded device reduced to 30 or something
you will experience a run out of free sockets very fast after some
connects and disconnects. This fixes prior problems regarding conflicts
for those who had problems with UaExpert 1.4.1 and newer. This relates
to #576 and #517
NetoLe 8 gadi atpakaļ
vecāks
revīzija
97b8eef02a
1 mainītis faili ar 7 papildinājumiem un 4 dzēšanām
  1. 7 4
      plugins/networklayer_tcp.c

+ 7 - 4
plugins/networklayer_tcp.c

@@ -391,11 +391,12 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, UA_Logger logger) {
 static size_t
 ServerNetworkLayerTCP_getJobs(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt16 timeout) {
     ServerNetworkLayerTCP *layer = nl->handle;
-    fd_set fdset;
+    fd_set fdset, errset;
     UA_Int32 highestfd = setFDSet(layer, &fdset);
+    setFDSet(layer, &errset);
     struct timeval tmptv = {0, timeout * 1000};
     UA_Int32 resultsize;
-    resultsize = select(highestfd+1, &fdset, NULL, NULL, &tmptv);
+    resultsize = select(highestfd+1, &fdset, NULL, &errset, &tmptv);
     if(resultsize < 0) {
         *jobs = NULL;
         return 0;
@@ -426,8 +427,10 @@ ServerNetworkLayerTCP_getJobs(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt1
     size_t j = 0;
     UA_ByteString buf = UA_BYTESTRING_NULL;
     for(size_t i = 0; i < layer->mappingsSize && j < (size_t)resultsize; i++) {
-        if(!UA_fd_isset(layer->mappings[i].sockfd, &fdset))
-            continue;
+        if(UA_fd_isset(layer->mappings[i].sockfd, &errset)) {}
+        else if(!UA_fd_isset(layer->mappings[i].sockfd, &fdset)) {
+          continue;
+        }
         UA_StatusCode retval = socket_recv(layer->mappings[i].connection, &buf, 0);
         if(retval == UA_STATUSCODE_GOOD) {
             js[j].job.binaryMessage.connection = layer->mappings[i].connection;