17 #ifdef USE_SOLARIS_PORT
19 static const int SOLARIS_PORT_POLL_READ
= POLLIN
;
20 static const int SOLARIS_PORT_POLL_WRITE
= POLLOUT
;
21 static const int SOLARIS_PORT_POLL_READ_WRITE
= POLLIN
& POLLOUT
;
23 static int fdevent_solaris_port_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
24 if (fde_ndx
< 0) return -1;
26 if (0 != port_dissociate(ev
->port_fd
, PORT_SOURCE_FD
, fd
)) {
27 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
28 "port_dissociate failed: ", strerror(errno
), ", dying");
38 static int fdevent_solaris_port_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
39 const int* user_data
= NULL
;
41 if ((events
& FDEVENT_IN
) && (events
& FDEVENT_OUT
)) {
42 user_data
= &SOLARIS_PORT_POLL_READ_WRITE
;
43 } else if (events
& FDEVENT_IN
) {
44 user_data
= &SOLARIS_PORT_POLL_READ
;
45 } else if (events
& FDEVENT_OUT
) {
46 user_data
= &SOLARIS_PORT_POLL_WRITE
;
49 if (0 != port_associate(ev
->port_fd
, PORT_SOURCE_FD
, fd
, *user_data
, (void*) user_data
)) {
50 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
51 "port_associate failed: ", strerror(errno
), ", dying");
61 static int fdevent_solaris_port_event_get_revent(fdevents
*ev
, size_t ndx
) {
64 e
= ev
->port_events
[ndx
].portev_events
;
65 if (e
& POLLIN
) events
|= FDEVENT_IN
;
66 if (e
& POLLOUT
) events
|= FDEVENT_OUT
;
67 if (e
& POLLERR
) events
|= FDEVENT_ERR
;
68 if (e
& POLLHUP
) events
|= FDEVENT_HUP
;
69 if (e
& POLLPRI
) events
|= FDEVENT_PRI
;
70 if (e
& POLLNVAL
) events
|= FDEVENT_NVAL
;
75 static int fdevent_solaris_port_event_get_fd(fdevents
*ev
, size_t ndx
) {
76 return ev
->port_events
[ndx
].portev_object
;
79 static int fdevent_solaris_port_event_next_fdndx(fdevents
*ev
, int ndx
) {
84 i
= (ndx
< 0) ? 0 : ndx
+ 1;
89 static void fdevent_solaris_port_free(fdevents
*ev
) {
91 free(ev
->port_events
);
94 /* if there is any error it will return the return values of port_getn, otherwise it will return number of events **/
95 static int fdevent_solaris_port_poll(fdevents
*ev
, int timeout_ms
) {
98 unsigned int available_events
, wait_for_events
= 0;
101 struct timespec timeout
;
103 timeout
.tv_sec
= timeout_ms
/1000L;
104 timeout
.tv_nsec
= (timeout_ms
% 1000L) * 1000000L;
106 /* get the number of file descriptors with events */
107 if ((ret
= port_getn(ev
->port_fd
, ev
->port_events
, 0, &wait_for_events
, &timeout
)) < 0) return ret
;
109 /* wait for at least one event */
110 if (0 == wait_for_events
) wait_for_events
= 1;
112 available_events
= wait_for_events
;
114 /* get the events of the file descriptors */
115 if ((ret
= port_getn(ev
->port_fd
, ev
->port_events
, ev
->maxfds
, &available_events
, &timeout
)) < 0) {
116 /* if errno == ETIME and available_event == wait_for_events we didn't get any events */
117 /* for other errors we didn't get any events either */
118 if (!(errno
== ETIME
&& wait_for_events
!= available_events
)) return ret
;
121 for (i
= 0; i
< available_events
; ++i
) {
122 user_data
= (const int *) ev
->port_events
[i
].portev_user
;
124 if ((ret
= port_associate(ev
->port_fd
, PORT_SOURCE_FD
, ev
->port_events
[i
].portev_object
,
125 *user_data
, (void*) user_data
)) < 0) {
126 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
127 "port_associate failed: ", strerror(errno
), ", dying");
135 return available_events
;
138 int fdevent_solaris_port_init(fdevents
*ev
) {
139 ev
->type
= FDEVENT_HANDLER_SOLARIS_PORT
;
141 ev->x = fdevent_solaris_port_##x;
149 SET(event_next_fdndx
);
151 SET(event_get_revent
);
153 if ((ev
->port_fd
= port_create()) < 0) {
154 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
155 "port_create() failed (", strerror(errno
), "), try to set server.event-handler = \"poll\" or \"select\"");
160 ev
->port_events
= malloc(ev
->maxfds
* sizeof(*ev
->port_events
));
161 force_assert(NULL
!= ev
->port_events
);
167 int fdevent_solaris_port_init(fdevents
*ev
) {
170 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
171 "solaris-eventports not supported, try to set server.event-handler = \"poll\" or \"select\"");