Wisp 1.3.1 C++ Unit Test Coverage
Current view: top level - ssrc/wisp/service/detail - FreeBSDEventPort.cc (source / functions) Hit Total Coverage
Test: Wisp 1.3.1 C++ Unit Tests Lines: 29 44 65.9 %
Date: 2017-01-16 Functions: 7 7 100.0 %
Branches: 13 56 23.2 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright 2009 Savarese Software Research Corporation
       2                 :            :  *
       3                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       4                 :            :  * you may not use this file except in compliance with the License.
       5                 :            :  * You may obtain a copy of the License at
       6                 :            :  *
       7                 :            :  *     http://www.savarese.com/software/ApacheLicense-2.0
       8                 :            :  *
       9                 :            :  * Unless required by applicable law or agreed to in writing, software
      10                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      11                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :            :  * See the License for the specific language governing permissions and
      13                 :            :  * limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include <ssrc/wisp/service/detail/FreeBSDEventPort.h>
      17                 :            : 
      18                 :            : #include <cerrno>
      19                 :            : #include <cstring>
      20                 :            : #include <unistd.h>
      21                 :            : 
      22                 :            : #include <sys/time.h>
      23                 :            : 
      24                 :            : __BEGIN_NS_SSRC_WISP_SERVICE
      25                 :            : 
      26                 :            : namespace detail {
      27                 :            : 
      28                 :          3 : FreeBSDEventPort::FreeBSDEventPort() SSRC_DECL_THROW(std::runtime_error) :
      29                 :          3 :   _kqueue_fd(::kqueue())
      30                 :            : {
      31         [ -  + ]:          3 :   if(_kqueue_fd < 0) {
      32   [ #  #  #  #  :          0 :     throw std::runtime_error(std::strerror(errno));
                   #  # ]
      33                 :            :   }
      34                 :          3 : }
      35                 :            : 
      36                 :          6 : FreeBSDEventPort::~FreeBSDEventPort() {
      37                 :          3 :   ::close(_kqueue_fd);
      38                 :          3 : }
      39                 :            : 
      40                 :            : // Note: the EventPort abstraction defeats some of the efficiencies
      41                 :            : // of kqueue by forcing event handlers to be registered one at a time.
      42                 :            : // Also it doesn't map nicely onto kqueue, so it's rather klugey and
      43                 :            : // limited in function.  A redesign of the EventPort concept should be
      44                 :            : // performed, taking into account the kqueue idiosyncracies.
      45                 :            : 
      46                 :            : // returns false only on EACCES
      47                 :          3 : bool FreeBSDEventPort::add(int fd,
      48                 :            :                            const events_type events,
      49                 :            :                            void *user_data,
      50                 :            :                            const bool once)
      51                 :            :   SSRC_DECL_THROW(std::runtime_error)
      52                 :            : {
      53                 :            :   event_type event;
      54                 :            : 
      55                 :          3 :   EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, user_data);
      56                 :            : 
      57         [ -  + ]:          3 :   if(events & Write) {
      58                 :          0 :     event.filter = EVFILT_WRITE;
      59                 :            :   }
      60                 :            : 
      61         [ -  + ]:          3 :   if(once) {
      62                 :          0 :     event.flags |= EV_ONESHOT;
      63                 :            :   }
      64                 :            : 
      65         [ +  - ]:          3 :   int err = ::kevent(_kqueue_fd, &event, 1, 0, 0, 0);
      66                 :            : 
      67         [ +  - ]:          3 :   if(err == 0) {
      68                 :          3 :     return true;
      69   [ #  #  #  # ]:          0 :   } else if(errno != EACCES) {
      70   [ #  #  #  #  :          0 :     throw std::runtime_error(std::strerror(errno));
                   #  # ]
      71                 :            :   }
      72                 :            : 
      73                 :          0 :   return false;
      74                 :            : }
      75                 :            : 
      76                 :          3 : bool FreeBSDEventPort::remove(int fd, events_type events)
      77                 :            :   SSRC_DECL_THROW(std::runtime_error)
      78                 :            : {
      79                 :          3 :   int err = 0;
      80                 :            :   event_type event;
      81                 :            : 
      82                 :          3 :   EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
      83                 :            : 
      84         [ +  - ]:          3 :   if(events & Read) {
      85         [ +  - ]:          3 :     err = ::kevent(_kqueue_fd, &event, 1, 0, 0, 0);
      86                 :            :   }
      87                 :            : 
      88         [ -  + ]:          3 :   if(events & Write) {
      89                 :          0 :     event.filter = EVFILT_WRITE;
      90         [ #  # ]:          0 :     err |= ::kevent(_kqueue_fd, &event, 1, 0, 0, 0);
      91                 :            :   }
      92                 :            : 
      93         [ +  - ]:          3 :   if(err == 0) {
      94                 :          3 :     return true;
      95   [ #  #  #  # ]:          0 :   } else if(errno != ENOENT) {
      96   [ #  #  #  #  :          0 :     throw std::runtime_error(std::strerror(errno));
                   #  # ]
      97                 :            :   }
      98                 :            : 
      99                 :          0 :   return false;
     100                 :            : }
     101                 :            : 
     102                 :          6 : int FreeBSDEventPort::wait(event_type *events, int max_events, int timeout) {
     103                 :            :   // For some reason we can't pick up timespec if we include <sys/time.h>
     104                 :            :   // in FreeBSD namespace, so we have to use this kluge with a cast.
     105                 :            :   ::timespec to;
     106                 :          6 :   ::timespec *pto = &to;
     107                 :            : 
     108         [ +  - ]:          6 :   if(timeout > 0) {
     109                 :          6 :     to.tv_sec = timeout / 1000;
     110                 :          6 :     to.tv_nsec = (timeout % 1000)*1000000;
     111         [ #  # ]:          0 :   } else if(timeout == 0) {
     112                 :          0 :     to.tv_sec = 0;
     113                 :          0 :     to.tv_nsec = 0;
     114                 :            :   } else
     115                 :          0 :     pto = 0;
     116                 :            : 
     117         [ +  - ]:          6 :   return kevent(_kqueue_fd, 0, 0, events, max_events, pto);
     118                 :            : }
     119                 :            : 
     120                 :            : }
     121                 :            : 
     122   [ +  -  +  - ]:          6 : __END_NS_SSRC_WISP_SERVICE