struct llist {
char *data;
size_t len;
struct llist *next;
};
static struct llist *ll_buffers = 0;
static int llbuf_num = 500;
void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
if(!do_exit) {
// 先分配了一个 len的空间,把驱动内获取到的数据 copy到这个空间里面,填充rpt的 data和len
struct llist *rpt = (struct llist*)malloc(sizeof(struct llist));
rpt->data = (char*)malloc(len);
memcpy(rpt->data, buf, len);
rpt->len = len;
rpt->next = NULL;
pthread_mutex_lock(&ll_mutex);
if (ll_buffers == NULL) {//第一次运行的时候,把rpt赋值给 ll_buffers。
ll_buffers = rpt;
} else {
struct llist *cur = ll_buffers;
int num_queued = 0;
while (cur->next != NULL) {// 获取 这个list 串接的长度
cur = cur->next;
num_queued++;
}
if(llbuf_num && llbuf_num == num_queued-2){ //如果这个 list的长度到达了500,把头上的 llist释放掉。把ll_buffers指向第二个。
struct llist *curelem;
free(ll_buffers->data);
curelem = ll_buffers->next;
free(ll_buffers);
ll_buffers = curelem;
}
cur->next = rpt;// 把最新获取的数据 rpt 放到llist的最后。
if (num_queued > global_numq) //统计 llist 的 queued num 的增减
printf("ll+, now %d\n", num_queued);
else if (num_queued < global_numq)
printf("ll-, now %d\n", num_queued);
global_numq = num_queued;
}
pthread_cond_signal(&cond);
pthread_mutex_unlock(&ll_mutex);
}
}
static void *tcp_worker(void *arg)
{
struct llist *curelem,*prev;
int bytesleft,bytessent, index;
struct timeval tv= {1,0};
struct timespec ts;
struct timeval tp;
fd_set writefds;
int r = 0;
while(1) {
if(do_exit)
pthread_exit(0);
pthread_mutex_lock(&ll_mutex);
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec+5;
ts.tv_nsec = tp.tv_usec * 1000;
r = pthread_cond_timedwait(&cond, &ll_mutex, &ts);// 这个里面有lock和unlock动作
if(r == ETIMEDOUT) {
pthread_mutex_unlock(&ll_mutex);
printf("worker cond timeout\n");
sighandler(0);
pthread_exit(NULL);
}
curelem = ll_buffers;
ll_buffers = 0;
pthread_mutex_unlock(&ll_mutex);
while(curelem != 0) {
bytesleft = curelem->len;
index = 0;
bytessent = 0;
while(bytesleft > 0) {
FD_ZERO(&writefds);
FD_SET(s, &writefds);
tv.tv_sec = 1;
tv.tv_usec = 0;
r = select(s+1, NULL, &writefds, NULL, &tv);
if(r) {
bytessent = send(s, &curelem->data[index], bytesleft, 0);
bytesleft -= bytessent;
index += bytessent;
}
if(bytessent == SOCKET_ERROR || do_exit) {
printf("worker socket bye\n");
sighandler(0);
pthread_exit(NULL);
}
}
prev = curelem;
curelem = curelem->next;
free(prev->data);
free(prev);
}
}
}