You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ak...@apache.org on 2010/05/08 05:38:39 UTC

svn commit: r942300 - in /trafficserver/traffic/branches/UserFiber: UFIO.C UFIO.H

Author: akundu
Date: Sat May  8 03:38:38 2010
New Revision: 942300

URL: http://svn.apache.org/viewvc?rev=942300&view=rev
Log:
support for sendto recvfrom

Modified:
    trafficserver/traffic/branches/UserFiber/UFIO.C
    trafficserver/traffic/branches/UserFiber/UFIO.H

Modified: trafficserver/traffic/branches/UserFiber/UFIO.C
URL: http://svn.apache.org/viewvc/trafficserver/traffic/branches/UserFiber/UFIO.C?rev=942300&r1=942299&r2=942300&view=diff
==============================================================================
--- trafficserver/traffic/branches/UserFiber/UFIO.C (original)
+++ trafficserver/traffic/branches/UserFiber/UFIO.C Sat May  8 03:38:38 2010
@@ -302,22 +302,27 @@ void UFIO::accept(UFIOAcceptThreadChoose
     }
 }
 
-ssize_t UFIO::read(void *buf, size_t nbyte, TIME_IN_US timeout)
+UFIOScheduler* UFIO::getUFIOS()
 {
-    UFIOScheduler* tmpUfios = _ufios;
-    if(!tmpUfios)
+    UFIOScheduler* tmpUfios = 0;
+    //
+    //find the ufios for this thread - this map operation should only be done once
+    ThreadFiberIOSchedulerMap::iterator index = UFIOScheduler::_tfiosscheduler.find(pthread_self());
+    if(index != UFIOScheduler::_tfiosscheduler.end())
+        tmpUfios = index->second;
+    else
     {
-        //find the ufios for this thread - this map operation should only be done once
-        ThreadFiberIOSchedulerMap::iterator index = UFIOScheduler::_tfiosscheduler.find(pthread_self());
-        if(index != UFIOScheduler::_tfiosscheduler.end())
-            tmpUfios = index->second;
-        else
-        {
-            cerr<<"couldnt find thread io scheduler for thread "<<pthread_self()<<" - please create one first and assign to the thread - current size of that info = "<<UFIOScheduler::_tfiosscheduler.size()<<endl;
-            exit(1); //TODO: may not be necessary to exit here
-        }
+        cerr<<"couldnt find thread io scheduler for thread "<<pthread_self()<<" - please create one first and assign to the thread - current size of that info = "<<UFIOScheduler::_tfiosscheduler.size()<<endl;
+        exit(1); //TODO: may not be necessary to exit here
     }
 
+    return tmpUfios;
+}
+
+ssize_t UFIO::read(void *buf, size_t nbyte, TIME_IN_US timeout)
+{
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
+
     //we read everything there was to be read the last time, so this time wait to read
     if(!_amtReadLastTimeEqualToAskedAmt) 
     {
@@ -331,7 +336,6 @@ ssize_t UFIO::read(void *buf, size_t nby
             return -1;
     }
 
-
     _amtReadLastTimeEqualToAskedAmt = false;
     ssize_t n = 0;;
     while(1)
@@ -369,19 +373,7 @@ ssize_t UFIO::read(void *buf, size_t nby
 
 ssize_t UFIO::write(const void *buf, size_t nbyte, TIME_IN_US timeout)
 {
-    UFIOScheduler* tmpUfios = _ufios;
-    if(!tmpUfios)
-    {
-        //find the ufios for this thread - this map operation should only be done once
-        ThreadFiberIOSchedulerMap::iterator index = UFIOScheduler::_tfiosscheduler.find(pthread_self());
-        if(index != UFIOScheduler::_tfiosscheduler.end())
-            tmpUfios = index->second;
-        else
-        {
-            cerr<<"couldnt find thread io scheduler for thread "<<pthread_self()<<" - please create one first and assign to the thread - current size of that info = "<<UFIOScheduler::_tfiosscheduler.size()<<endl;
-            exit(1); //TODO: may not be necessary to exit here
-        }
-    }
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
 
     ssize_t n = 0;;
     unsigned int amtWritten = 0;
@@ -428,20 +420,7 @@ int UFIO::connect(const struct sockaddr 
 
 
     //find the scheduler for this request
-    UFIOScheduler* tmpUfios = _ufios;
-    if(!tmpUfios)
-    {
-        //find the ufios for this thread - this map operation should only be done once
-        ThreadFiberIOSchedulerMap::iterator index = UFIOScheduler::_tfiosscheduler.find(pthread_self());
-        if(index != UFIOScheduler::_tfiosscheduler.end())
-            tmpUfios = index->second;
-        else
-        {
-            cerr<<"couldnt find thread io scheduler for thread "<<pthread_self()<<" - please create one first and assign to the thread - current size of that info = "<<UFIOScheduler::_tfiosscheduler.size()<<endl;
-            return -1;
-        }
-    }
-
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
 
     int n = 0;
     int err = 0;
@@ -478,6 +457,175 @@ int UFIO::connect(const struct sockaddr 
     return 0;
 }
 
+int UFIO::sendto(const char *buf, int len, const struct sockaddr *to, int tolen, TIME_IN_US timeout)
+{
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
+
+    ssize_t n = 0;;
+    unsigned int amtWritten = 0;
+    while(1)
+    {
+        n = ::sendto(_fd, buf+amtWritten, len-amtWritten, 0, to, tolen);
+        if(n > 0)
+        {
+            amtWritten += n;
+            if((int)amtWritten == len)
+                return amtWritten;
+            else
+                continue;
+        }
+        else if(n < 0)
+        {
+            _errno = errno;
+            if((errno == EAGAIN) || (errno == EWOULDBLOCK))
+            {
+                _errno = 0;
+                if(!tmpUfios->setupForWrite(this, timeout))
+                {
+                    _errno = errno;
+                    return -1;
+                }
+            }
+            else if(errno == EINTR)
+                continue;
+            else
+                break;
+        }
+        else if(n == 0)
+            break;
+    }
+    return n;
+}
+
+int UFIO::sendmsg(const struct msghdr *msg, 
+                  int flags,
+	              TIME_IN_US timeout)
+{
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
+
+    ssize_t n = 0;;
+    while(1)
+    {
+        n = ::sendmsg(_fd, msg, flags); 
+        if(n > 0)
+            continue;
+        else if(n < 0)
+        {
+            _errno = errno;
+            if((errno == EAGAIN) || (errno == EWOULDBLOCK))
+            {
+                _errno = 0;
+                if(!tmpUfios->setupForWrite(this, timeout))
+                {
+                    _errno = errno;
+                    return -1;
+                }
+            }
+            else if(errno == EINTR)
+                continue;
+            else
+                break;
+        }
+        else if(n == 0)
+            break;
+    }
+    return n;
+}
+
+int UFIO::recvfrom(char *buf, 
+                   int len, 
+                   struct sockaddr *from,
+		           int *fromlen, 
+                   TIME_IN_US timeout)
+{
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
+
+    //we read everything there was to be read the last time, so this time wait to read
+    if(!_amtReadLastTimeEqualToAskedAmt) 
+    {
+        //wait for something to read first
+        if(!tmpUfios->setupForRead(this, timeout))
+        {
+            _errno = errno;
+            return -1;
+        }
+        if(_errno == ETIMEDOUT) //setupForRead will return w/ success however it will set the errno to ETIMEDOUT if a timeout occurred
+            return -1;
+    }
+
+    _amtReadLastTimeEqualToAskedAmt = false;
+    ssize_t n = 0;;
+    while(1)
+    {
+        n = ::recvfrom(_fd, buf, len, 0, from, (socklen_t *)fromlen);
+        if(n > 0)
+        {
+            _amtReadLastTimeEqualToAskedAmt = (n != len) ? false : true;
+            return n;
+        }
+        else if(n < 0)
+        {
+            if((errno == EAGAIN) || (errno == EWOULDBLOCK))
+            {
+                _errno = 0;
+                if(!tmpUfios->setupForRead(this, timeout))
+                {
+                    _errno = errno;
+                    return -1;
+                }
+            }
+            else if(errno == EINTR)
+                continue;
+            else
+            {
+                _errno = errno;
+                break;
+            }
+        }
+        else if(n == 0)
+            break;
+    }
+    return n;
+}
+
+int UFIO::recvmsg(struct msghdr *msg, 
+                  int flags,
+	              TIME_IN_US timeout)
+{
+    UFIOScheduler* tmpUfios = _ufios ? _ufios : getUFIOS();
+
+    ssize_t n = 0;
+    while(1)
+    {
+        n = ::recvmsg(_fd, msg, flags);
+        if(n > 0)
+            return n;
+        else if(n < 0)
+        {
+            if((errno == EAGAIN) || (errno == EWOULDBLOCK))
+            {
+                _errno = 0;
+                if(!tmpUfios->setupForRead(this, timeout))
+                {
+                    _errno = errno;
+                    return -1;
+                }
+            }
+            else if(errno == EINTR)
+                continue;
+            else
+            {
+                _errno = errno;
+                break;
+            }
+        }
+        else if(n == 0)
+            break;
+    }
+    return n;
+}
+
+
 
 ThreadFiberIOSchedulerMap UFIOScheduler::_tfiosscheduler;
 EpollUFIOScheduler::EpollUFIOScheduler(UF* uf, unsigned int maxFds)
@@ -864,3 +1012,5 @@ void EpollUFIOScheduler::waitForEvents(T
     myScheduler->_notifyArgs = 0;
     myScheduler->_notifyFunc = 0;
 }
+
+

Modified: trafficserver/traffic/branches/UserFiber/UFIO.H
URL: http://svn.apache.org/viewvc/trafficserver/traffic/branches/UserFiber/UFIO.H?rev=942300&r1=942299&r2=942300&view=diff
==============================================================================
--- trafficserver/traffic/branches/UserFiber/UFIO.H (original)
+++ trafficserver/traffic/branches/UserFiber/UFIO.H Sat May  8 03:38:38 2010
@@ -79,6 +79,23 @@ struct UFIO
     //another call to this fxn if the return was == to nbyte
     ssize_t read(void *buf, size_t nbyte, TIME_IN_US timeout = 0);
     ssize_t write(const void *buf, size_t nbyte, TIME_IN_US timeout = 0);
+    int sendto(const char *msg, 
+                  int len,
+	              const struct sockaddr *to, 
+                  int tolen, 
+                  TIME_IN_US timeout);
+    int sendmsg(const struct msghdr *msg, 
+                   int flags,
+	               TIME_IN_US timeout);
+    int recvfrom(char *buf, 
+                    int len, 
+                    struct sockaddr *from,
+		            int *fromlen, 
+                    TIME_IN_US timeout);
+    int recvmsg(struct msghdr *msg, 
+                   int flags,
+	               TIME_IN_US timeout);
+
     bool close();
 
     bool setFd(int fd, bool makeNonBlocking = true);
@@ -109,6 +126,7 @@ protected:
 
     int                         _lastEpollFlag;
     bool                        _amtReadLastTimeEqualToAskedAmt;
+    static UFIOScheduler* getUFIOS();
 };
 inline unsigned int UFIO::getErrno() const { return _errno; }
 inline int UFIO::getFd() const { return _fd; }