Branch data Line data Source code
1 : : /*
2 : : * Copyright 2009 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <cerrno>
18 : : #include <cstring>
19 : : #include <unistd.h>
20 : :
21 : : #include <ssrc/wisp/service/detail/SolarisEventPort.h>
22 : :
23 : : __BEGIN_NS_SSRC_WISP_SERVICE
24 : :
25 : : // Note: uintptr_t, uint_t, and timespec_t don't register as types when
26 : : // accessed via Solaris namespace. Must be macros.
27 : :
28 : : namespace detail {
29 : :
30 : 3 : SolarisEventPort::SolarisEventPort() SSRC_DECL_THROW(std::runtime_error) :
31 : 3 : _port_fd(Solaris::port_create())
32 : : {
33 [ - + ]: 3 : if(_port_fd < 0)
34 [ # # ][ # # ]: 0 : throw std::runtime_error(std::strerror(errno));
[ # # ][ # # ]
35 : 3 : }
36 : :
37 : 3 : SolarisEventPort::~SolarisEventPort() {
38 : 3 : ::close(_port_fd);
39 : 3 : }
40 : :
41 : 11 : bool SolarisEventPort::add(int fd,
42 : : const events_type events,
43 : : void *user_data,
44 : : const bool once)
45 : : SSRC_DECL_THROW(std::runtime_error)
46 : : {
47 : : int err =
48 : : Solaris::port_associate(_port_fd, PORT_SOURCE_FD,
49 : 11 : static_cast<uintptr_t>(fd), events, user_data);
50 : :
51 [ + - ]: 11 : if(err == 0) {
52 : 11 : return true;
53 : : } else
54 [ # # ][ # # ]: 0 : throw std::runtime_error(std::strerror(errno));
[ # # ][ # # ]
55 : : }
56 : :
57 : 3 : bool SolarisEventPort::remove(int fd)
58 : : SSRC_DECL_THROW(std::runtime_error)
59 : : {
60 : : int err = Solaris::port_dissociate(_port_fd, PORT_SOURCE_FD,
61 : 3 : static_cast<uintptr_t>(fd));
62 : :
63 [ - + ]: 3 : if(err == 0) {
64 : 0 : return true;
65 [ - + ]: 3 : } else if(errno != ENOENT)
66 [ # # ][ # # ]: 0 : throw std::runtime_error(std::strerror(errno));
[ # # ][ # # ]
67 : :
68 : 3 : return false;
69 : : }
70 : :
71 : :
72 : : // For now, we follow Linux epoll API for EventPort::wait concept.
73 : : // returns negative value on error, otherwise number of descriptors
74 : : // timeout is in milliseconds, -1 for indefinite wait..
75 : 8 : int SolarisEventPort::wait(event_type *events, int max_events, int timeout) {
76 : 8 : uint_t num_events(1);
77 : : timespec_t to;
78 : 8 : timespec_t *pto = &to;
79 : :
80 [ + - ]: 8 : if(timeout > 0) {
81 : 8 : to.tv_sec = timeout / 1000;
82 : 8 : timeout-=(to.tv_sec * 1000);
83 : 8 : to.tv_nsec = timeout*1000000;
84 [ # # ]: 0 : } else if(timeout == 0) {
85 : 0 : to.tv_sec = 0;
86 : 0 : to.tv_nsec = 0;
87 : : } else
88 : 0 : pto = 0;
89 : :
90 : : int err =
91 : : Solaris::port_getn(_port_fd, events, static_cast<uint_t>(max_events),
92 : 8 : &num_events, pto);
93 : :
94 : : // NOTE: It appears port_getn will return negative values less than -1
95 : : // (e.g., -22052315) on success, so we can't assume only 0 is success.
96 : : // Instead we assume any value other than -1 is success. One timeout,
97 : : // port_getn sets num_events to 0, hence || errno == ETIME.
98 [ - + ][ # # ]: 8 : if(err != -1 || errno == ETIME) {
[ + - ]
99 : 8 : return static_cast<int>(num_events);
100 : : }
101 : :
102 : 8 : return -1;
103 : : }
104 : :
105 : : }
106 : :
107 [ + - ][ + - ]: 6 : __END_NS_SSRC_WISP_SERVICE
|