blob: 80e6c42eeed2bb40285c9015088d95c16429e19b [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
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020024#include <errno.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010025#include <osmocom/core/write_queue.h>
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010026
Harald Welte2777ecd2011-08-17 14:23:42 +020027/*! \addtogroup write_queue
28 * @{
29 */
30
31/*! \file write_queue.c */
32
33/*! \brief Select loop function for write queue handling
34 * \param[in] fd osmocom file descriptor
35 * \param[in] what bit-mask of events that have happened
36 *
37 * This function is provided so that it can be registered with the
38 * select loop abstraction code (\ref osmo_fd::cb).
39 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020040int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010041{
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020042 struct osmo_wqueue *queue;
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020043 int rc;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010044
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020045 queue = container_of(fd, struct osmo_wqueue, bfd);
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010046
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020047 if (what & BSC_FD_READ) {
48 rc = queue->read_cb(fd);
49 if (rc == -EBADFD)
50 goto err_badfd;
51 }
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010052
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020053 if (what & BSC_FD_EXCEPT) {
54 rc = queue->except_cb(fd);
55 if (rc == -EBADFD)
56 goto err_badfd;
57 }
Holger Hans Peter Freyther4052c812010-04-08 10:58:20 +020058
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010059 if (what & BSC_FD_WRITE) {
60 struct msgb *msg;
61
62 fd->when &= ~BSC_FD_WRITE;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010063
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010064 /* the queue might have been emptied */
65 if (!llist_empty(&queue->msg_queue)) {
66 --queue->current_length;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010067
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010068 msg = msgb_dequeue(&queue->msg_queue);
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020069 rc = queue->write_cb(fd, msg);
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010070 msgb_free(msg);
71
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020072 if (rc == -EBADFD)
73 goto err_badfd;
74
Holger Hans Peter Freyther76681ba2011-02-15 00:42:19 +010075 if (!llist_empty(&queue->msg_queue))
76 fd->when |= BSC_FD_WRITE;
77 }
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010078 }
79
Daniel Willmannbd8a89d2014-06-10 10:02:24 +020080err_badfd:
81 /* Return value is not checked in osmo_select_main() */
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010082 return 0;
83}
84
Harald Welte2777ecd2011-08-17 14:23:42 +020085/*! \brief Initialize a \ref osmo_wqueue structure
86 * \param[in] queue Write queue to operate on
87 * \param[in] max_length Maximum length of write queue
88 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020089void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010090{
91 queue->max_length = max_length;
92 queue->current_length = 0;
93 queue->read_cb = NULL;
94 queue->write_cb = NULL;
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +020095 queue->bfd.cb = osmo_wqueue_bfd_cb;
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +010096 INIT_LLIST_HEAD(&queue->msg_queue);
97}
98
Harald Welte2777ecd2011-08-17 14:23:42 +020099/*! \brief Enqueue a new \ref msgb into a write queue
100 * \param[in] queue Write queue to be used
101 * \param[in] data to-be-enqueued message buffer
102 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +0200103int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
Holger Hans Peter Freyther8df932a2010-02-26 20:30:32 +0100104{
105// if (queue->current_length + 1 >= queue->max_length)
106// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
107
108 ++queue->current_length;
109 msgb_enqueue(&queue->msg_queue, data);
110 queue->bfd.when |= BSC_FD_WRITE;
111
112 return 0;
113}
Holger Hans Peter Freyther99a263f2010-03-26 09:20:22 +0100114
Harald Welte2777ecd2011-08-17 14:23:42 +0200115/*! \brief Clear a \ref osmo_wqueue
116 * \param[in] queue Write queue to be cleared
117 *
118 * This function will clear (remove/release) all messages in it.
119 */
Pablo Neira Ayuso9111d932011-05-07 12:42:51 +0200120void osmo_wqueue_clear(struct osmo_wqueue *queue)
Holger Hans Peter Freyther99a263f2010-03-26 09:20:22 +0100121{
122 while (!llist_empty(&queue->msg_queue)) {
123 struct msgb *msg = msgb_dequeue(&queue->msg_queue);
124 msgb_free(msg);
125 }
126
127 queue->current_length = 0;
128 queue->bfd.when &= ~BSC_FD_WRITE;
129}
Harald Welte2777ecd2011-08-17 14:23:42 +0200130
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200131/*! @} */