mirror of
https://github.com/transmission/transmission
synced 2025-03-09 21:54:09 +00:00
get some pieces of the new tracker code into svn...
This commit is contained in:
parent
d2d7d01df2
commit
2bf071543b
9 changed files with 510 additions and 1 deletions
|
@ -1,4 +1,4 @@
|
|||
AM_CPPFLAGS = -I. -I$(top_srcdir) $(LIBEVENT_CPPFLAGS) -D__TRANSMISSION__
|
||||
AM_CPPFLAGS = -I. -I@top_srcdir@ -D__TRANSMISSION__
|
||||
|
||||
noinst_LIBRARIES = libtransmission.a
|
||||
|
||||
|
@ -23,11 +23,14 @@ libtransmission_a_SOURCES = \
|
|||
net.c \
|
||||
peer.c \
|
||||
platform.c \
|
||||
ptrarray.c \
|
||||
publish.c \
|
||||
ratecontrol.c \
|
||||
sha1.c \
|
||||
shared.c \
|
||||
strlcat.c \
|
||||
strlcpy.c \
|
||||
timer.c \
|
||||
torrent.c \
|
||||
tracker.c \
|
||||
transmission.c \
|
||||
|
@ -61,9 +64,12 @@ noinst_HEADERS = \
|
|||
peertree.h \
|
||||
peerutils.h \
|
||||
platform.h \
|
||||
ptrarray.h \
|
||||
publish.h \
|
||||
ratecontrol.h \
|
||||
sha1.h \
|
||||
shared.h \
|
||||
timer.h \
|
||||
tracker.h \
|
||||
transmission.h \
|
||||
trcompat.h \
|
||||
|
|
186
libtransmission/ptrarray.c
Normal file
186
libtransmission/ptrarray.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* memmove */
|
||||
|
||||
#include "ptrarray.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define GROW 32
|
||||
|
||||
struct tr_ptrArray_s
|
||||
{
|
||||
void ** items;
|
||||
int n_items;
|
||||
int n_alloc;
|
||||
};
|
||||
|
||||
tr_ptrArray_t*
|
||||
tr_ptrArrayNew( void )
|
||||
{
|
||||
tr_ptrArray_t * p;
|
||||
|
||||
p = tr_new( tr_ptrArray_t, 1 );
|
||||
p->n_items = 0;
|
||||
p->n_alloc = GROW;
|
||||
p->items = tr_new( void*, p->n_alloc );
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ptrArrayFree( tr_ptrArray_t * t )
|
||||
{
|
||||
assert( t != NULL );
|
||||
assert( t->items != NULL );
|
||||
|
||||
tr_free( t->items );
|
||||
tr_free( t );
|
||||
}
|
||||
|
||||
void**
|
||||
tr_ptrArrayPeek( tr_ptrArray_t * t, int * size )
|
||||
{
|
||||
*size = t->n_items;
|
||||
return t->items;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ptrArraySize( const tr_ptrArray_t * t )
|
||||
{
|
||||
return t->n_items;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ptrArrayEmpty( const tr_ptrArray_t * t )
|
||||
{
|
||||
return t->n_items == 0;
|
||||
}
|
||||
|
||||
void
|
||||
tr_ptrArrayClear( tr_ptrArray_t * t )
|
||||
{
|
||||
t->n_items = 0;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ptrArrayInsert( tr_ptrArray_t * t, void * ptr, int pos )
|
||||
{
|
||||
if( pos<0 || pos>t->n_items )
|
||||
pos = t->n_items;
|
||||
|
||||
if( t->n_items >= t->n_alloc ) {
|
||||
t->n_alloc = t->n_items + GROW;
|
||||
t->items = tr_renew( void*, t->items, t->n_alloc );
|
||||
}
|
||||
|
||||
memmove( t->items + pos + 1,
|
||||
t->items + pos,
|
||||
sizeof(void*) * (t->n_items - pos));
|
||||
|
||||
t->items[pos] = ptr;
|
||||
t->n_items++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ptrArrayAppend( tr_ptrArray_t * t, void * ptr )
|
||||
{
|
||||
return tr_ptrArrayInsert( t, ptr, -1 );
|
||||
}
|
||||
|
||||
void
|
||||
tr_ptrArrayErase( tr_ptrArray_t * t, int begin, int end )
|
||||
{
|
||||
assert( begin >= 0 );
|
||||
if( end < 0 ) end = t->n_items;
|
||||
assert( end > begin );
|
||||
assert( end <= t->n_items );
|
||||
|
||||
memmove( t->items + begin,
|
||||
t->items + end,
|
||||
sizeof(void*) * (t->n_items - end) );
|
||||
|
||||
t->n_items -= (end - begin);
|
||||
}
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
||||
int
|
||||
tr_ptrArrayLowerBound( const tr_ptrArray_t * t,
|
||||
void * ptr,
|
||||
int compare( const void *,const void * ),
|
||||
int * exact_match )
|
||||
{
|
||||
int c = -1;
|
||||
int len = t->n_items;
|
||||
int first = 0;
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
int half = len / 2;
|
||||
int middle = first + half;
|
||||
c = compare( t->items[middle], ptr );
|
||||
if( c < 0 ) {
|
||||
first = middle + 1;
|
||||
len = len - half - 1;
|
||||
} else if (!c ) {
|
||||
if( exact_match )
|
||||
*exact_match = 1;
|
||||
return middle;
|
||||
break;
|
||||
} else {
|
||||
len = half;
|
||||
}
|
||||
}
|
||||
|
||||
if( exact_match )
|
||||
*exact_match = 0;
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
int
|
||||
tr_ptrArrayInsertSorted( tr_ptrArray_t * t,
|
||||
void * ptr,
|
||||
int compare(const void*,const void*) )
|
||||
{
|
||||
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, NULL );
|
||||
return tr_ptrArrayInsert( t, ptr, pos );
|
||||
}
|
||||
|
||||
void*
|
||||
tr_ptrArrayFindSorted( tr_ptrArray_t * t,
|
||||
void * ptr,
|
||||
int compare(const void*,const void*) )
|
||||
{
|
||||
int match;
|
||||
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, &match );
|
||||
return match ? t->items[pos] : NULL;
|
||||
}
|
||||
|
||||
void*
|
||||
tr_ptrArrayRemoveSorted( tr_ptrArray_t * t,
|
||||
void * ptr,
|
||||
int compare(const void*,const void*) )
|
||||
{
|
||||
void * ret = NULL;
|
||||
int match;
|
||||
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, &match );
|
||||
if( match ) {
|
||||
ret = t->items[pos];
|
||||
tr_ptrArrayErase( t, pos, pos+1 );
|
||||
}
|
||||
return ret;
|
||||
}
|
37
libtransmission/ptrarray.h
Normal file
37
libtransmission/ptrarray.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#ifndef _TR_POINTERS_H_
|
||||
#define _TR_POINTERS_H_
|
||||
|
||||
/**
|
||||
* A simple pointer array that resizes itself dynamically.
|
||||
*/
|
||||
typedef struct tr_ptrArray_s tr_ptrArray_t;
|
||||
|
||||
tr_ptrArray_t * tr_ptrArrayNew ( void );
|
||||
void tr_ptrArrayFree ( tr_ptrArray_t* );
|
||||
void** tr_ptrArrayPeek ( tr_ptrArray_t*, int * size );
|
||||
void** tr_ptrArrayBase ( tr_ptrArray_t* );
|
||||
void tr_ptrArrayClear ( tr_ptrArray_t* );
|
||||
int tr_ptrArrayInsert ( tr_ptrArray_t*, void*, int pos );
|
||||
int tr_ptrArrayAppend ( tr_ptrArray_t*, void* );
|
||||
void tr_ptrArrayErase ( tr_ptrArray_t*, int begin, int end );
|
||||
int tr_ptrArraySize ( const tr_ptrArray_t* );
|
||||
int tr_ptrArrayEmpty ( const tr_ptrArray_t* );
|
||||
|
||||
int tr_ptrArrayInsertSorted( tr_ptrArray_t*, void*,
|
||||
int compare(const void*,const void*) );
|
||||
void* tr_ptrArrayRemoveSorted( tr_ptrArray_t*, void*,
|
||||
int compare(const void*,const void*) );
|
||||
void* tr_ptrArrayFindSorted ( tr_ptrArray_t*, void*,
|
||||
int compare(const void*,const void*) );
|
||||
|
||||
#endif
|
72
libtransmission/publish.c
Normal file
72
libtransmission/publish.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#include "list.h"
|
||||
#include "publish.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct tr_publisher_node
|
||||
{
|
||||
tr_delivery_func * func;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
struct tr_publisher_s
|
||||
{
|
||||
tr_list_t * list;
|
||||
};
|
||||
|
||||
tr_publisher_t*
|
||||
tr_publisherNew( void )
|
||||
{
|
||||
return tr_new0( tr_publisher_t, 1 );
|
||||
}
|
||||
|
||||
void
|
||||
tr_publisherFree( tr_publisher_t * p )
|
||||
{
|
||||
tr_list_free( &p->list );
|
||||
tr_free( p );
|
||||
}
|
||||
|
||||
tr_publisher_tag
|
||||
tr_publisherSubscribe ( tr_publisher_t * p,
|
||||
tr_delivery_func func,
|
||||
void * user_data )
|
||||
{
|
||||
struct tr_publisher_node * node = tr_new( struct tr_publisher_node, 1 );
|
||||
node->func = func;
|
||||
node->user_data = user_data;
|
||||
tr_list_append( &p->list, node );
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
tr_publisherUnsubscribe( tr_publisher_t * p,
|
||||
tr_publisher_tag tag )
|
||||
{
|
||||
tr_list_remove_data( &p->list, tag );
|
||||
tr_free( tag );
|
||||
}
|
||||
|
||||
void
|
||||
tr_publisherPublish( tr_publisher_t * p,
|
||||
void * source,
|
||||
void * event )
|
||||
{
|
||||
tr_list_t * walk;
|
||||
for( walk=p->list; walk!=NULL; )
|
||||
{
|
||||
tr_list_t * next = walk->next;
|
||||
struct tr_publisher_node * node = (struct tr_publisher_node*)walk->data;
|
||||
(node->func)(source, event, node->user_data);
|
||||
walk = next;
|
||||
}
|
||||
}
|
49
libtransmission/publish.h
Normal file
49
libtransmission/publish.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#ifndef _TR_PUBLISHER_H_
|
||||
#define _TR_PUBLISHER_H_
|
||||
|
||||
/**
|
||||
*** A lightweight implementation of the 'Observable' design pattern.
|
||||
**/
|
||||
|
||||
typedef struct tr_publisher_s tr_publisher_t;
|
||||
|
||||
typedef void * tr_publisher_tag;
|
||||
|
||||
typedef void tr_delivery_func( void * source,
|
||||
void * event,
|
||||
void * user_data );
|
||||
|
||||
/**
|
||||
*** Observer API
|
||||
**/
|
||||
|
||||
tr_publisher_tag tr_publisherSubscribe ( tr_publisher_t * publisher,
|
||||
tr_delivery_func delivery_func,
|
||||
void * user_data );
|
||||
|
||||
void tr_publisherUnsubscribe ( tr_publisher_t * publisher,
|
||||
tr_publisher_tag tag );
|
||||
|
||||
/**
|
||||
*** Observable API
|
||||
**/
|
||||
|
||||
tr_publisher_t * tr_publisherNew ( void );
|
||||
|
||||
void tr_publisherFree ( tr_publisher_t * publisher );
|
||||
|
||||
void tr_publisherPublish ( tr_publisher_t * publisher,
|
||||
void * source,
|
||||
void * event );
|
||||
|
||||
#endif
|
104
libtransmission/timer.c
Normal file
104
libtransmission/timer.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h> /* u_char for event.h */
|
||||
#include <event.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "timer.h"
|
||||
#include "utils.h"
|
||||
|
||||
typedef int tr_timer_func ( void * user_data );
|
||||
typedef void tr_data_free_func( void * user_data );
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
struct timer_node
|
||||
{
|
||||
struct event event;
|
||||
tr_timer_func * func;
|
||||
void * user_data;
|
||||
tr_data_free_func * free_func;
|
||||
struct timeval tv;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
static void
|
||||
unref( struct timer_node * node, int count )
|
||||
{
|
||||
assert( node != NULL );
|
||||
assert( node->refcount > 0 );
|
||||
|
||||
node->refcount -= count;
|
||||
if( node->refcount > 0 )
|
||||
return;
|
||||
|
||||
if( node->free_func != NULL )
|
||||
(node->free_func)( node->user_data );
|
||||
event_del( &node->event );
|
||||
tr_free( node );
|
||||
}
|
||||
|
||||
void
|
||||
tr_timerFree( struct timer_node ** node )
|
||||
{
|
||||
assert( node != NULL );
|
||||
|
||||
if( *node )
|
||||
{
|
||||
unref( *node, 1 );
|
||||
*node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
timerCB( int fd UNUSED, short event UNUSED, void * arg )
|
||||
{
|
||||
struct timer_node * node = (struct timer_node *) arg;
|
||||
int val;
|
||||
|
||||
++node->refcount;
|
||||
val = (node->func)(node->user_data);
|
||||
if( !val )
|
||||
unref( node, 2 );
|
||||
else {
|
||||
timeout_add( &node->event, &node->tv );
|
||||
unref( node, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tr_timer_tag
|
||||
tr_timerNew( tr_timer_func func,
|
||||
void * user_data,
|
||||
tr_data_free_func free_func,
|
||||
int timeout_milliseconds )
|
||||
{
|
||||
struct timer_node * node;
|
||||
const unsigned long microseconds = timeout_milliseconds * 1000;
|
||||
|
||||
assert( func != NULL );
|
||||
assert( timeout_milliseconds >= 0 );
|
||||
|
||||
node = tr_new( struct timer_node, 1 );
|
||||
node->func = func;
|
||||
node->user_data = user_data;
|
||||
node->free_func = free_func;
|
||||
node->refcount = 1;
|
||||
node->tv.tv_sec = microseconds / 1000000;
|
||||
node->tv.tv_usec = microseconds % 1000000;
|
||||
timeout_set( &node->event, timerCB, node );
|
||||
timeout_add( &node->event, &node->tv );
|
||||
return node;
|
||||
}
|
37
libtransmission/timer.h
Normal file
37
libtransmission/timer.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#ifndef _TR_TIMER_H_
|
||||
#define _TR_TIMER_H_
|
||||
|
||||
typedef struct timer_node * tr_timer_tag;
|
||||
|
||||
/**
|
||||
* Calls timer_func(user_data) after the specified interval.
|
||||
* The timer is freed if timer_func returns zero.
|
||||
* Otherwise, it's called again after the same interval.
|
||||
*
|
||||
* If free_func is non-NULL, free_func(user_data) is called
|
||||
* by the timer when it's freed (either from timer_func returning
|
||||
* zero or from a client call to tr_timerFree). This is useful
|
||||
* if user_data has resources that need to be freed.
|
||||
*/
|
||||
tr_timer_tag tr_timerNew( int timer_func( void * user_data ),
|
||||
void * user_data,
|
||||
void free_func( void * user_data ),
|
||||
int timeout_milliseconds );
|
||||
|
||||
/**
|
||||
* Frees a timer and sets its tag to NULL.
|
||||
*/
|
||||
void tr_timerFree( tr_timer_tag * tag );
|
||||
|
||||
|
||||
#endif
|
|
@ -33,6 +33,8 @@
|
|||
#include <unistd.h> /* stat */
|
||||
#include <dirent.h> /* opendir */
|
||||
|
||||
#include <event.h>
|
||||
|
||||
#include "transmission.h"
|
||||
#include "fdlimit.h"
|
||||
#include "list.h"
|
||||
|
@ -61,6 +63,19 @@ tr_peerIdNew ( char * buf, int buflen )
|
|||
buf[TR_ID_LEN] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
libeventThreadFunc( void * unused UNUSED )
|
||||
{
|
||||
tr_dbg( "libevent thread starting" );
|
||||
event_init( );
|
||||
for ( ;; )
|
||||
{
|
||||
event_dispatch( );
|
||||
tr_wait( 50 ); /* 1/20th of a second */
|
||||
}
|
||||
tr_dbg( "libevent thread exiting" );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* tr_init
|
||||
|
@ -72,6 +87,8 @@ tr_handle_t * tr_init( const char * tag )
|
|||
tr_handle_t * h;
|
||||
int i;
|
||||
|
||||
tr_threadNew( libeventThreadFunc, NULL, "libeventThreadFunc" );
|
||||
|
||||
tr_msgInit();
|
||||
tr_netInit();
|
||||
tr_netResolveThreadInit();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h> /* for size_t */
|
||||
|
||||
void tr_msgInit( void );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue