/* * Copyright (C) 2021 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _TOOS_QUEUE_H_ #define _TOOS_QUEUE_H_ #include #include #include #include /* EBUSY */ #include /* pthread_mutex_t, pthread_cond_t */ /** * returned error codes, everything except Q_OK should be < 0 */ typedef enum QErros { Q_OK = 0, Q_ERR_INVALID = -1, Q_ERR_LOCK = -2, Q_ERR_MEM = -3, Q_ERR_NONEWDATA = -4, Q_ERR_INVALID_ELEMENT = -5, Q_ERR_INVALID_CB = -6, Q_ERR_NUM_ELEMENTS = -7 } QErros; namespace ATools { class Queue { public: /** * initializes a queue with unlimited elements * */ Queue(); /** * initializes a queue with max element count * * maxElement - maximum number of elements which are allowed in the queue, == 0 for "unlimited" * */ Queue(uint32_t maxElement); /** * just like Queue() * additionally you can specify a comparator function so that your elements are ordered in the queue * elements will only be ordered if you create the queue with this method * the compare function should return 0 if both elements are the same, < 0 if the first is smaller * and > 0 if the second is smaller * * asc - sort in ascending order if not 0 * cmp - comparator function, NULL will create an error * */ Queue(bool ascendingOrder, int (*cmp)(void *, void *)); /** * initializes a queue,limit the queue max element count and set the order rule * * maxElement - maximum number of elements which are allowed in the queue, == 0 for "unlimited" * */ Queue(uint32_t maxElement, bool ascendingOrder, int (*cmp)(void *, void *)); virtual ~Queue(); /** * put a new element at the end of the queue * will produce an error if you called setAllowedNewData() * * e - the element * * returns 0 if everything worked, > 0 if max_elements is reached, < 0 if error occurred */ int32_t push(void *ele); /** * the same as push(), but will wait if max_elements is reached, * until setAllowedNewData(true) is called or elements are removed * * e - the element * * returns 0 if everything worked, < 0 if error occurred */ int32_t pushAndWait(void *ele); /** * get the first element of the queue * * e - pointer which will be set to the element * * returns 0 if everything worked, < 0 if error occurred */ int32_t pop(void **e); /** * the same as pop(), but will wait if no elements are in the queue, * until setAllowedNewData(true) is called or new elements are added * * q - the queue * e - pointer which will be set to the element * * returns 0 if everything worked, < 0 if error occurred */ int32_t popAndWait(void **e); /** * peek the pos element */ int32_t peek(void **e, int32_t pos); /** * only flush element,but not free element's data * returns 0 on success, other failed */ int32_t flush(); /** * flush element,and call ff function to notify element action * fcb - the callback function * returns 0 on success, other failed */ int32_t flushAndCallback(void *userdata, void (*fcb)(void *userdata, void *ele)); /** * get element count in queue */ int32_t getCnt(); /** * checking the queue is empty? */ bool isEmpty(); /** * set queue allow add new element */ int32_t setAllowedNewData(bool allowed); /** * check allowed new element flag */ bool isAllowedNewData(); private: typedef struct Element{ void *data; struct Element *next; } Element; int32_t _init(); /** * destroys a queue. * queue will be locked. * * ff - callback function,this func will be invoked when a element been flushed */ int32_t _release(); /** * locks the queue * returns 0 on success, else not usable */ int32_t _lock(); /** * unlocks the queue * returns 0 on success, else not usable */ int32_t _unlock(); /** * flushes a queue. * deletes all elements in the queue. * queue _has_ to be locked. * * ff - callback function,this func will be invoked when a element been flushed */ int32_t _flushElements(void *userdata, void (*fcb)(void *userdata, void *ele)); /** * adds an element to the queue. * when isWait is true, the put element thread will block * if the queue is full until getElement be invoked * queue _has_ to be locked. * * ele - the element * isWait - if false,this func will return immediately * if true, this func will block when queue is reached the queue capability * until getElement be invoked * * returns < 0 => error, 0 okay */ int32_t _pushElement(void *ele, bool isWait); /** * pop the special element from the queue. * the cmp param is a compare function,this function will * compare every element of the queue with cmpeEle,if equal cmp will return 0 * or return < 0 if the element in the queue less than cmpEle or return > 0 if * the element in the queue bigger than cmpEle * * queue has to be locked. * * e - element pointer * isWait - check if block when there are no elements in the queue * cmp - comparator function, NULL will create an error * cmpEle - element with which should be compared * * returns < 0 => error, 0 okay */ int32_t _popElement(void **e, bool isWait, int (*cmp)(void *, void *), void *cmpEle); int32_t _peekElement(void **e, int32_t pos); Element *mUsedFirstElement; Element *mUsedLastElement; uint32_t mUsedElementCnts; //the cnt of elements in queue uint32_t mCapability; //the capability of the queue bool mAllowedNewData; // no new data allowed //sorted queue bool mSort; bool mAscendingOrder; int (*cmpEleFun)(void *, void *); pthread_mutex_t mMutex; pthread_cond_t mCondGet; pthread_cond_t mCondPut; }; } #endif // _TOOS_QUEUE_H_