blob: cef40f83c55f61c23d38de70ef35ef3f743b86b1 [file] [log] [blame]
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +01001/* Generic write queue implementation */
2/*
3 * (C) 2010 by Holger Hans Peter Freyther
4 * (C) 2010 by On-Waves
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010024#include <osmocom/core/write_queue.h>
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010025
Harald Welte2777ecd2011-08-17 14:23:42 +020026/*! \addtogroup write_queue
27 * @{
28 */
29
30/*! \file write_queue.c */
31
32/*! \brief Select loop function for write queue handling
33 * \param[in] fd osmocom file descriptor
34 * \param[in] what bit-mask of events that have happened
35 *
36 * This function is provided so that it can be registered with the
37 * select loop abstraction code (\ref osmo_fd::cb).
38 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020039int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010040{
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020041 struct osmo_wqueue *queue;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010042
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020043 queue = container_of(fd, struct osmo_wqueue, bfd);
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010044
45 if (what & BSC_FD_READ)
46 queue->read_cb(fd);
47
Holger Hans Peter Freyther4052c812010-04-08 10:58:20 +020048 if (what & BSC_FD_EXCEPT)
49 queue->except_cb(fd);
50
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010051 if (what & BSC_FD_WRITE) {
52 struct msgb *msg;
53
54 fd->when &= ~BSC_FD_WRITE;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010055
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010056 /* the queue might have been emptied */
57 if (!llist_empty(&queue->msg_queue)) {
58 --queue->current_length;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010059
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010060 msg = msgb_dequeue(&queue->msg_queue);
61 queue->write_cb(fd, msg);
62 msgb_free(msg);
63
64 if (!llist_empty(&queue->msg_queue))
65 fd->when |= BSC_FD_WRITE;
66 }
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010067 }
68
69 return 0;
70}
71
Harald Welte2777ecd2011-08-17 14:23:42 +020072/*! \brief Initialize a \ref osmo_wqueue structure
73 * \param[in] queue Write queue to operate on
74 * \param[in] max_length Maximum length of write queue
75 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020076void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010077{
78 queue->max_length = max_length;
79 queue->current_length = 0;
80 queue->read_cb = NULL;
81 queue->write_cb = NULL;
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020082 queue->bfd.cb = osmo_wqueue_bfd_cb;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010083 INIT_LLIST_HEAD(&queue->msg_queue);
84}
85
Harald Welte2777ecd2011-08-17 14:23:42 +020086/*! \brief Enqueue a new \ref msgb into a write queue
87 * \param[in] queue Write queue to be used
88 * \param[in] data to-be-enqueued message buffer
89 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020090int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010091{
92// if (queue->current_length + 1 >= queue->max_length)
93// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
94
95 ++queue->current_length;
96 msgb_enqueue(&queue->msg_queue, data);
97 queue->bfd.when |= BSC_FD_WRITE;
98
99 return 0;
100}
Holger Hans Peter Freyther99a263f2010-03-26 09:20:22 +0100101
Harald Welte2777ecd2011-08-17 14:23:42 +0200102/*! \brief Clear a \ref osmo_wqueue
103 * \param[in] queue Write queue to be cleared
104 *
105 * This function will clear (remove/release) all messages in it.
106 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +0200107void osmo_wqueue_clear(struct osmo_wqueue *queue)
Holger Hans Peter Freyther99a263f2010-03-26 09:20:22 +0100108{
109 while (!llist_empty(&queue->msg_queue)) {
110 struct msgb *msg = msgb_dequeue(&queue->msg_queue);
111 msgb_free(msg);
112 }
113
114 queue->current_length = 0;
115 queue->bfd.when &= ~BSC_FD_WRITE;
116}
Harald Welte2777ecd2011-08-17 14:23:42 +0200117
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200118/*! @} */