72
70
return ( addr->s_addr == 0xFFFFFFFF );
75
static tr_thread_t * resolveThread;
76
static tr_lock_t * resolveLock;
77
static tr_cond_t * resolveCond;
78
static volatile int resolveDie;
79
static tr_resolve_t * resolveQueue;
81
static void resolveRelease ( tr_resolve_t * );
82
static void resolveFunc ( void * );
94
/***********************************************************************
95
* tr_netResolveThreadInit
96
***********************************************************************
97
* Initializes the static variables used for resolution and launch the
98
* gethostbyname thread.
99
**********************************************************************/
100
void tr_netResolveThreadInit( void )
104
resolveLock = tr_lockNew( );
105
resolveCond = tr_condNew( );
106
resolveThread = tr_threadNew( resolveFunc, NULL, "resolve" );
109
/***********************************************************************
110
* tr_netResolveThreadClose
111
***********************************************************************
112
* Notices the gethostbyname thread that is should terminate. Doesn't
113
* wait until it does, in case it is stuck in a resolution: we let it
114
* die and clean itself up.
115
**********************************************************************/
116
void tr_netResolveThreadClose( void )
118
tr_lockLock( resolveLock );
120
tr_lockUnlock( resolveLock );
121
tr_condSignal( resolveCond );
125
/***********************************************************************
127
***********************************************************************
128
* Adds an address to the resolution queue.
129
**********************************************************************/
130
tr_resolve_t * tr_netResolveInit( const char * address )
132
tr_resolve_t * r = tr_new0( tr_resolve_t, 1 );
133
r->status = TR_NET_WAIT;
134
r->address = strdup( address );
138
tr_lockLock( resolveLock );
146
for( iter = resolveQueue; iter->next; iter = iter->next );
149
tr_lockUnlock( resolveLock );
150
tr_condSignal( resolveCond );
155
/***********************************************************************
157
***********************************************************************
158
* Checks the current status of a resolution.
159
**********************************************************************/
160
tr_tristate_t tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr )
164
tr_lockLock( resolveLock );
166
if( ret == TR_NET_OK )
170
tr_lockUnlock( resolveLock );
175
/***********************************************************************
177
***********************************************************************
179
**********************************************************************/
180
void tr_netResolveClose( tr_resolve_t * r )
185
/***********************************************************************
187
***********************************************************************
188
* The allocated tr_resolve_t structures should be freed when
189
* tr_netResolveClose was called *and* it was removed from the queue.
190
* This can happen in any order, so we use a refcount to know we can
192
**********************************************************************/
193
static void resolveRelease( tr_resolve_t * r )
195
if( --r->refcount < 1 )
202
/***********************************************************************
204
***********************************************************************
205
* Keeps waiting for addresses to resolve, and removes them from the
206
* queue once resolution is done.
207
**********************************************************************/
208
static void resolveFunc( void * arg UNUSED )
211
struct hostent * host;
213
tr_lockLock( resolveLock );
217
if( !( r = resolveQueue ) )
219
tr_condWait( resolveCond, resolveLock );
223
/* Blocking resolution */
224
tr_lockUnlock( resolveLock );
225
host = gethostbyname( r->address );
226
tr_lockLock( resolveLock );
230
memcpy( &r->addr, host->h_addr, host->h_length );
231
r->status = TR_NET_OK;
235
r->status = TR_NET_ERROR;
238
resolveQueue = r->next;
243
tr_lockUnlock( resolveLock );
244
tr_lockFree( resolveLock );
246
while( ( r = resolveQueue ) )
248
resolveQueue = r->next;
254
74
/***********************************************************************
256
76
**********************************************************************/
258
static int makeSocketNonBlocking( int s )
79
makeSocketNonBlocking( int fd )
261
unsigned long flags = 1;
262
if( ioctlsocket( s, FIONBIO, &flags) == SOCKET_ERROR )
263
#elif defined(__BEOS__)
265
if( setsockopt( s, SOL_SOCKET, SO_NONBLOCK,
266
&flags, sizeof( int ) ) < 0 )
85
if( setsockopt( fd, SOL_SOCKET, SO_NONBLOCK,
86
&flags, sizeof( int ) ) < 0 )
269
if( ( flags = fcntl( s, F_GETFL, 0 ) ) < 0 ||
270
fcntl( s, F_SETFL, flags | O_NONBLOCK ) < 0 )
88
if( evutil_make_socket_nonblocking( fd ) )
273
tr_err( "Couldn't set socket to non-blocking mode (%s)",
274
strerror( sockerrno ) );
91
tr_err( "Couldn't set socket to non-blocking mode (%s)",
92
strerror( sockerrno ) );
282
static int createSocket( int type, int priority )
102
createSocket( int type, int priority )
285
if( ( s = tr_fdSocketCreate( type, priority ) ) < 0 )
289
return makeSocketNonBlocking( s );
104
return makeSocketNonBlocking( tr_fdSocketCreate( type, priority ) );