• libubox


    摘自:https://my.oschina.net/u/1777349/blog/599651

    摘自:https://blog.csdn.net/chengxing6375/article/details/100838511

    libubox是openwrt新版本中的一个基础库,在openwrt.14.07中有很多应用程序是基于libubox开发的。(如:uhttpd,libubus等)。

    libubox主要提供一下两种功能:

            1、提供一套基于事件驱动的机制。

            2、提供多种开发支持接口。(如:链表、kv链表、平衡查找二叉树、md5、json)

        使用libubox开发的好处有如下几点:

            1、可以使程序基于事件驱动,从而可实现在单线程中处理多个任务。

            2、基于libubox提供的开发API可以加快开发进度的同事提高程序的稳定性。

            3、能更好的将程序融入openwrt的架构中,因为新的openwrt的很多应用和库都基于libubox开发的。

        综上所述,libubox是您玩新版openwrt必修的一个东东,相信它也值得大家去研究学习。

     事件框架

    uloop.c/h:

    主框架
    /**
     * 初始化事件循环
     */
     int uloop_init(void)
     /**
     * 事件循环主处理入口
     */
     void uloop_run(void)
     /**
     * 销毁事件循环
     */
     void uloop_done(void)
    描述符结构体
    struct uloop_fd {
        uloop_fd_handler cb;    /** 描述符事件处理函数 */
        int fd;                 /** 文件描述符,调用者初始化 */
        bool eof;                       
        bool error;                     
        bool registered;        /** 是否已注册到uloop中 */     
        uint8_t flags;  
    };
    定时器结构体
    struct uloop_timeout {    
        struct list_head list;  
        bool pending;               
        uloop_timeout_handler cb; /** 定时事件处理函数 */
        struct timeval time;      /** 时间结构体 */
    };
    进程结构体
    struct uloop_process { 
     struct list_head list;              
        bool pending;                   
        uloop_process_handler cb;       /** 进程事件处理函数 */
        pid_t pid;                      /** 进程号*/
    };
    描述符事件处理函数
    typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events)
    定时器事件处理函数
    typedef void (*uloop_timeout_handler)(struct uloop_timeout *t)
    进程事件处理函数
    typedef void (*uloop_process_handler)(struct uloop_process *c, int ret)
    
    事件标志
    #define ULOOP_READ          (1 << 0)
    #define ULOOP_WRITE         (1 << 1)
    #define ULOOP_EDGE_TRIGGER  (1 << 2)
    #define ULOOP_BLOCKING      (1 << 3)
    #define ULOOP_EVENT_MASK    (ULOOP_READ | ULOOP_WRITE)
    定时器事件
    /**
     * 注册一个新定时器
     */
     int uloop_timeout_add(struct uloop_timeout *timeout)
     /**
     * 设置定时器超时时间(毫秒),并添加
     */
     int uloop_timeout_set(struct uloop_timeout *timeout, int msecs)
     /**
     * 销毁指定定时器
     */
     int uloop_timeout_cancel(struct uloop_timeout *timeout)
     /**
     * 获取定时器还剩多长时间超时
     */
     int uloop_timeout_remaining(struct uloop_timeout *timeout)
    描述符事件
    /**
     * 注册一个新描述符到事件处理循环
     */
     int uloop_fd_add(struct uloop_fd *sock, unsigned int flags)
     /** 
     * 从事件处理循环中销毁指定描述符
     */
     int uloop_fd_delete(struct uloop_fd *sock)
    进程事件
    /**
     * 注册新进程到事件处理循环
     */
     int uloop_process_add(struct uloop_process *p)
     /**
     * 从事件处理循环中销毁指定进程
     */
     int uloop_process_delete(struct uloop_process *p)
    //任务队列结构体
    struct runqueue {
        struct safe_list tasks_active;      /** 活动任务队列 */
        struct safe_list tasks_inactive;    /** 不活动任务队列 */
        struct uloop_timeout timeout;    
        int running_tasks;      /** 当前活动任务数目 */
        int max_running_tasks;  /** 允许最大活动任务数目 */
        bool stopped;           /** 是否停止任务队列 */
        bool empty;             /** 任务队列(包括活动和不活动)是否为空 */
    
        /* called when the runqueue is emptied */
        void (*empty_cb)(struct runqueue *q);
    };
    
    //任务处理函数
    struct runqueue_task_type {    
        const char *name;    
        /*
         * called when a task is requested to run
         *
         * The task is removed from the list before this callback is run. It
         * can re-arm itself using runqueue_task_add.
         */
        void (*run)(struct runqueue *q, struct runqueue_task *t);   
         /*
         * called to request cancelling a task
         *
         * int type is used as an optional hint for the method to be used when
         * cancelling the task, e.g. a signal number for processes. Calls
         * runqueue_task_complete when done.
         */
        void (*cancel)(struct runqueue *q, struct runqueue_task *t, int type);    
        /*
         * called to kill a task. must not make any calls to runqueue_task_complete,
         * it has already been removed from the list.
         */
        void (*kill)(struct runqueue *q, struct runqueue_task *t);
    };
    
    //任务结构体
    struct runqueue_task {    
        struct safe_list list;    
        const struct runqueue_task_type *type;    
        struct runqueue *q;    
        void (*complete)(struct runqueue *q, struct runqueue_task *t);    
        struct uloop_timeout timeout;    
        int run_timeout;    /** >0表示规定此任务执行只有run_timeout毫秒 */
        int cancel_timeout; /** >0表示规则任务延取消操作执行只有run_timeout毫秒*/
        int cancel_type;    
        bool queued;        /** 此任务是否已加入任务队列中 */
        bool running;       /** 此任务是否活动,即已在活动队列中 */
        bool cancelled;     /** 此任务是否已被取消 */
    };
    
    //进程任务结构体
    struct runqueue_process {
        struct runqueue_task task;
        struct uloop_process proc;
    };
    任务队列操作函数
    
    /**
     * 初始化任务队列
     */
     void runqueue_init(struct runqueue *q)
     /** 
     * 取消所有任务队列
     */
     void runqueue_cancel(struct runqueue *q);
     /** 
     * 取消活动中的任务
     */
     void runqueue_cancel_active(struct runqueue *q);
     /** 
     * 取消不活动的任务 
     */
     void runqueue_cancel_pending(struct runqueue *q);
     /**
     * 杀死所有任务
     */
     void runqueue_kill(struct runqueue *q);
     /** 
     * 停止所有任务
     */
     void runqueue_stop(struct runqueue *q);
     /**
     * 重新开始任务
     */
     void runqueue_resume(struct runqueue *q);
    任务操作函数
    /**
     * 添加新任务到队列尾
     *
     * @running true-加入活动队列;false-加入不活动队列
     */
     void runqueue_task_add(struct runqueue *q, struct runqueue_task *t, bool running);
     /**
     * 添加新任务到队列头
     *
     * @running true-加入活动队列;false-加入不活动队列
     */
     void runqueue_task_add_first(struct runqueue *q, struct runqueue_task *t, 
    bool running);
    /**
     * 完全任务
     */
     void runqueue_task_complete(struct runqueue_task *t);
     /**
     * 取消任务
     */
     void runqueue_task_cancel(struct runqueue_task *t, int type);
     /**
     * 杀死任务
     */
     void runqueue_task_kill(struct runqueue_task *t);
    进程任务操作函数
    void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid);
    /**
     * to be used only from runqueue_process callbacks 
     */
     void runqueue_process_cancel_cb(struct runqueue *q, struct runqueue_task *t, int type);
     void runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *t);
    
    

    流缓冲管理

    ustream.c/h/ustream-fd.c:

    //流buffer结构体
    struct ustream_buf {
        struct ustream_buf *next;    
        char *data;     /** 指向上次操作buff开始地址 */
        char *tail;     /** 指向未使用buff开始地址 */
        char *end;      /** 指向buf结束地址 */
    
        char head[];    /** 指向buf开始地址 */
    };
    
    //流buffer结构体的链表
    struct ustream_buf_list {
        struct ustream_buf *head;       /** 指向第1块ustream_buf */
        struct ustream_buf *data_tail;  /** 指向未使用的ustream_buf */
        struct ustream_buf *tail;       /** 指向最后的ustream_buf */
    
        int (*alloc)(struct ustream *s, struct ustream_buf_list *l);    
        int data_bytes;    /** 已用存储空间大小 */
    
        int min_buffers;   /** 可存储最小的ustream_buf块个数 */
        int max_buffers;   /** 可存储最大的ustream_buf块个数 */
        int buffer_len;    /** 每块ustream_buf块存储空间大小 */
    
        int buffers;       /** ustream_buf块个数 */
        };
        
        //读写操作的缓冲结构及操作函数
    struct ustream { 
       struct ustream_buf_list r, w;    
       struct uloop_timeout state_change;    
       struct ustream *next;   
        /*
         * notify_read: (optional)
         * called by the ustream core to notify that new data is available
         * for reading.
         * must not free the ustream from this callback
         */
        void (*notify_read)(struct ustream *s, int bytes_new);    
        /*
         * notify_write: (optional)
         * called by the ustream core to notify that some buffered data has
         * been written to the stream.
         * must not free the ustream from this callback
         */
        void (*notify_write)(struct ustream *s, int bytes);   
         /*
         * notify_state: (optional)
         * called by the ustream implementation to notify that the read
         * side of the stream is closed (eof is set) or there was a write
         * error (write_error is set).
         * will be called again after the write buffer has been emptied when
         * the read side has hit EOF.
         */
        void (*notify_state)(struct ustream *s);    
        /*
         * write:
         * must be defined by ustream implementation, accepts new write data.
         * 'more' is used to indicate that a subsequent call will provide more
         * data (useful for aggregating writes)
         * returns the number of bytes accepted, or -1 if no more writes can
         * be accepted (link error)
         */
        int (*write)(struct ustream *s, const char *buf, int len, bool more);    
        /*
         * free: (optional)
         * defined by ustream implementation, tears down the ustream and frees data
         */
        void (*free)(struct ustream *s);   
         /*
         * set_read_blocked: (optional)
         * defined by ustream implementation, called when the read_blocked flag
         * changes
         */
        void (*set_read_blocked)(struct ustream *s);    
        /*
         * poll: (optional)
         * defined by the upstream implementation, called to request polling for
         * available data.
         * returns true if data was fetched.
         */
        bool (*poll)(struct ustream *s);    
        /*
         * ustream user should set this if the input stream is expected
         * to contain string data. the core will keep all data 0-terminated.
         */
        bool string_data;     /** 此ustream是否为字符串,true-是;false-否 */
        bool write_error;     /** 写出错,true-是;false-否 */
        bool eof, eof_write_done;    
        enum read_blocked_reason read_blocked;
    };    
    
    //流描述符结构体
    struct ustream_fd {
        struct ustream stream;    
        struct uloop_fd fd;
    };
    //流结构操作函数
    
    /**
     * ustream_fd_init: create a file descriptor ustream (uses uloop) 
     */
     void ustream_fd_init(struct ustream_fd *s, int fd)
     /**
     * ustream_init_defaults: fill default callbacks and options 
     */
     void ustream_init_defaults(struct ustream *s)
     /**
     * ustream_free: free all buffers and data associated with a ustream 
     */
     void ustream_free(struct ustream *s)
     
     //分配len空间
    char *ustream_reserve(struct ustream *s, int len, int *maxlen) 
    //移除读buffer中地一个数据结构
    void ustream_consume(struct ustream *s, int len)

    双向链表

    list.h:

    struct list_head {
        struct list_head *next;    
        struct list_head *prev;
    };
    
    #define LIST_HEAD_INIT(name) { &(name), &(name) }
    #define (name) struct list_head name = LIST_HEAD_INIT(name)
    static inline void INIT_LIST_HEAD(struct list_head *list)
    
    /** 
     * 加入链表头部
     */
     list_add(struct list_head *_new, struct list_head *head)
     /**
     * 加入链表尾部
     */
     list_add_tail(struct list_head *_new, struct list_head *head)
     
     /**
     * 把指定节点从链表中删除
     */
     list_del(struct list_head *entry)
     /**
     * 把指定节点从链表中删除,并初始此节点
     */
     list_del_init(struct list_head *entry)
     
     /**
     * 获取当前节点元素
     */
     list_entry(ptr, type, field)
     /**
     * 获取后一个节点元素
     */
     list_first_entry(ptr, type, field)
     /**
     * 获取前一个节点元素
     */
     list_last_entry(ptr, type, field)
     
     
     /**
     * 向后遍历链表,遍历过程不能操作链表,p为节点元素结构体
     */
     list_for_each_entry(p, h, field)
     /**
     * 向前遍历链表,遍历过程不能操作链表,p为链表结构体
     */
     list_for_each_prev(p, h)
  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/14201453.html
Copyright © 2020-2023  润新知