blob: cf45a62d46e185d63b0bdf7f224617e9c0cb1b3d [file] [log] [blame]
Benny Prijonof260e462007-04-30 21:03:32 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/sock_select.h>
20#include <pj/array.h>
21#include <pj/assert.h>
22#include <pj/os.h>
23#include "os_symbian.h"
24
25
26struct symbian_fd_set
27{
28 unsigned count;
29 CPjSocket *sock[FD_SETSIZE];
30};
31
32
33PJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)
34{
35 symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
36 fds->count = 0;
37}
38
39
40PJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)
41{
42 symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
43
44 PJ_ASSERT_ON_FAIL(fds->count < FD_SETSIZE, return);
45 fds->sock[fds->count++] = (CPjSocket*)fd;
46}
47
48
49PJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)
50{
51 symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
52 unsigned i;
53
54 for (i=0; i<fds->count; ++i) {
55 if (fds->sock[i] == (CPjSocket*)fd) {
56 pj_array_erase(fds->sock, sizeof(fds->sock[0]), fds->count, i);
57 --fds->count;
58 return;
59 }
60 }
61}
62
63
64PJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)
65{
66 symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
67 unsigned i;
68
69 for (i=0; i<fds->count; ++i) {
70 if (fds->sock[i] == (CPjSocket*)fd) {
71 return PJ_TRUE;
72 }
73 }
74
75 return PJ_FALSE;
76}
77
78PJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)
79{
80 symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
81 return fds->count;
82}
83
84
85PJ_DEF(int) pj_sock_select( int n,
86 pj_fd_set_t *readfds,
87 pj_fd_set_t *writefds,
88 pj_fd_set_t *exceptfds,
89 const pj_time_val *timeout)
90{
91 CPjTimeoutTimer *pjTimer;
92 unsigned i;
93
94 PJ_UNUSED_ARG(n);
95 PJ_UNUSED_ARG(writefds);
96 PJ_UNUSED_ARG(exceptfds);
97
98 if (timeout) {
99 pjTimer = PjSymbianOS::Instance()->SelectTimeoutTimer();
100 pjTimer->StartTimer(timeout->sec*1000 + timeout->msec);
101
102 } else {
103 pjTimer = NULL;
104 }
105
106 /* Scan for readable sockets */
107
108 if (readfds) {
109 symbian_fd_set *fds = (symbian_fd_set *)readfds;
110
111 do {
112 /* Scan sockets for readily available data */
113 for (i=0; i<fds->count; ++i) {
114 CPjSocket *pjsock = fds->sock[i];
115
116 if (pjsock->Reader()) {
117 if (pjsock->Reader()->HasData() && !pjsock->Reader()->IsActive()) {
118
119 /* Found socket with data ready */
120 PJ_FD_ZERO(readfds);
121 PJ_FD_SET((pj_sock_t)pjsock, readfds);
122
123 /* Cancel timer, if any */
124 if (pjTimer) {
125 pjTimer->Cancel();
126 }
127
128 /* Clear writable and exception fd_set */
129 if (writefds)
130 PJ_FD_ZERO(writefds);
131 if (exceptfds)
132 PJ_FD_ZERO(exceptfds);
133
134 return 1;
135
136 } else if (!pjsock->Reader()->IsActive())
137 pjsock->Reader()->StartRecvFrom();
138
139 } else {
140 pjsock->CreateReader();
141 pjsock->Reader()->StartRecvFrom();
142 }
143 }
144
145 PjSymbianOS::Instance()->WaitForActiveObjects();
146
147 } while (pjTimer==NULL || !pjTimer->HasTimedOut());
148 }
149
150
151 /* Timeout */
152
153 if (readfds)
154 PJ_FD_ZERO(readfds);
155 if (writefds)
156 PJ_FD_ZERO(writefds);
157 if (exceptfds)
158 PJ_FD_ZERO(exceptfds);
159
160 return 0;
161}
162