|
|
|
|
@ -861,20 +861,33 @@ static void table_put(struct rtpengine_table *t) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* must be called lock-free */
|
|
|
|
|
static inline void free_packet(struct re_stream_packet *packet) {
|
|
|
|
|
if (packet->skbuf)
|
|
|
|
|
kfree_skb(packet->skbuf);
|
|
|
|
|
kfree(packet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* caller is responsible for locking */
|
|
|
|
|
/* must be called lock-free */
|
|
|
|
|
static void clear_stream_packets(struct re_stream *stream) {
|
|
|
|
|
struct re_stream_packet *packet;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
LIST_HEAD(delete_list);
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&stream->packet_list_lock, flags);
|
|
|
|
|
|
|
|
|
|
while (!list_empty(&stream->packet_list)) {
|
|
|
|
|
DBG("clearing packet from queue\n");
|
|
|
|
|
packet = list_first_entry(&stream->packet_list, struct re_stream_packet, list_entry);
|
|
|
|
|
list_del(&packet->list_entry);
|
|
|
|
|
list_add(&packet->list_entry, &delete_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&stream->packet_list_lock, flags);
|
|
|
|
|
|
|
|
|
|
while (!list_empty(&delete_list)) {
|
|
|
|
|
packet = list_first_entry(&delete_list, struct re_stream_packet, list_entry);
|
|
|
|
|
list_del(&packet->list_entry);
|
|
|
|
|
free_packet(packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -2673,10 +2686,11 @@ static void del_stream(struct re_stream *stream, struct rtpengine_table *table)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream->eof = 1;
|
|
|
|
|
clear_stream_packets(stream);
|
|
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&stream->packet_list_lock, flags);
|
|
|
|
|
|
|
|
|
|
clear_stream_packets(stream);
|
|
|
|
|
|
|
|
|
|
DBG("stream is finished (EOF), waking up threads\n");
|
|
|
|
|
wake_up_interruptible(&stream->wq);
|
|
|
|
|
/* sleeping readers will now close files */
|
|
|
|
|
|