1 /* Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include "cras_rstream.h"
7 #include "cras_tm.h"
8 #include "cras_types.h"
9 #include "stream_list.h"
10 #include "utlist.h"
11
12 struct stream_list {
13 struct cras_rstream *streams;
14 struct cras_rstream *streams_to_delete;
15 stream_callback *stream_added_cb;
16 stream_callback *stream_removed_cb;
17 stream_create_func *stream_create_cb;
18 stream_destroy_func *stream_destroy_cb;
19 struct cras_tm *timer_manager;
20 struct cras_timer *drain_timer;
21 };
22
delete_streams(struct cras_timer * timer,void * data)23 static void delete_streams(struct cras_timer *timer, void *data)
24 {
25 struct cras_rstream *to_delete;
26 struct stream_list *list = (struct stream_list *)data;
27 int max_drain_delay = 0;
28
29 DL_FOREACH(list->streams_to_delete, to_delete) {
30 int drain_delay;
31
32 drain_delay = list->stream_removed_cb(to_delete);
33 if (drain_delay) {
34 max_drain_delay = MAX(max_drain_delay, drain_delay);
35 continue;
36 }
37 DL_DELETE(list->streams_to_delete, to_delete);
38 list->stream_destroy_cb(to_delete);
39 }
40
41 list->drain_timer = NULL;
42 if (max_drain_delay)
43 list->drain_timer = cras_tm_create_timer(list->timer_manager,
44 MAX(max_drain_delay, 10), delete_streams, list);
45 }
46
47 /*
48 * Exported Interface
49 */
50
stream_list_create(stream_callback * add_cb,stream_callback * rm_cb,stream_create_func * create_cb,stream_destroy_func * destroy_cb,struct cras_tm * timer_manager)51 struct stream_list *stream_list_create(stream_callback *add_cb,
52 stream_callback *rm_cb,
53 stream_create_func *create_cb,
54 stream_destroy_func *destroy_cb,
55 struct cras_tm *timer_manager)
56 {
57 struct stream_list *list = calloc(1, sizeof(struct stream_list));
58
59 list->stream_added_cb = add_cb;
60 list->stream_removed_cb = rm_cb;
61 list->stream_create_cb = create_cb;
62 list->stream_destroy_cb = destroy_cb;
63 list->timer_manager = timer_manager;
64 return list;
65 }
66
stream_list_destroy(struct stream_list * list)67 void stream_list_destroy(struct stream_list *list)
68 {
69 free(list);
70 }
71
stream_list_get(struct stream_list * list)72 struct cras_rstream *stream_list_get(struct stream_list *list)
73 {
74 return list->streams;
75 }
76
stream_list_add(struct stream_list * list,struct cras_rstream_config * stream_config,struct cras_rstream ** stream)77 int stream_list_add(struct stream_list *list,
78 struct cras_rstream_config *stream_config,
79 struct cras_rstream **stream)
80 {
81 int rc;
82
83 rc = list->stream_create_cb(stream_config, stream);
84 if (rc)
85 return rc;
86
87 DL_APPEND(list->streams, *stream);
88 rc = list->stream_added_cb(*stream);
89 if (rc) {
90 DL_DELETE(list->streams, *stream);
91 list->stream_destroy_cb(*stream);
92 }
93
94 return rc;
95 }
96
stream_list_rm(struct stream_list * list,cras_stream_id_t id)97 int stream_list_rm(struct stream_list *list, cras_stream_id_t id)
98 {
99 struct cras_rstream *to_remove;
100
101 DL_SEARCH_SCALAR(list->streams, to_remove, stream_id, id);
102 if (!to_remove)
103 return -EINVAL;
104 DL_DELETE(list->streams, to_remove);
105 DL_APPEND(list->streams_to_delete, to_remove);
106 if (list->drain_timer) {
107 cras_tm_cancel_timer(list->timer_manager, list->drain_timer);
108 list->drain_timer = NULL;
109 }
110 delete_streams(NULL, list);
111
112 return 0;
113 }
114
stream_list_rm_all_client_streams(struct stream_list * list,struct cras_rclient * rclient)115 int stream_list_rm_all_client_streams(struct stream_list *list,
116 struct cras_rclient *rclient)
117 {
118 struct cras_rstream *to_remove;
119 int rc = 0;
120
121 DL_FOREACH(list->streams, to_remove) {
122 if (to_remove->client == rclient) {
123 DL_DELETE(list->streams, to_remove);
124 DL_APPEND(list->streams_to_delete, to_remove);
125 }
126 }
127 if (list->drain_timer) {
128 cras_tm_cancel_timer(list->timer_manager, list->drain_timer);
129 list->drain_timer = NULL;
130 }
131 delete_streams(NULL, list);
132
133 return rc;
134
135 }
136
137