rtl_tcp代碼片段

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);
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章