+ vlc_cond_destroy (&bank->wait);
+ vlc_mutex_destroy (&bank->lock);
+}
+
+struct msg_subscription_t
+{
+ vlc_thread_t thread;
+ libvlc_int_t *instance;
+ msg_callback_t func;
+ msg_cb_data_t *opaque;
+ msg_item_t *items[VLC_MSG_QSIZE];
+ unsigned begin, end;
+ unsigned overruns;
+};
+
+static void *msg_thread (void *data)
+{
+ msg_subscription_t *sub = data;
+ msg_bank_t *bank = libvlc_bank (sub->instance);
+
+ /* TODO: finer-grained locking and/or msg_item_t refcount */
+ vlc_mutex_lock (&bank->lock);
+ mutex_cleanup_push (&bank->lock);
+
+ for (;;)
+ {
+ /* Wait for messages */
+ assert (sub->begin < VLC_MSG_QSIZE);
+ assert (sub->end < VLC_MSG_QSIZE);
+ while (sub->begin != sub->end)
+ {
+ sub->func (sub->opaque, sub->items[sub->begin], sub->overruns);
+ if (++sub->begin == VLC_MSG_QSIZE)
+ sub->begin = 0;
+ sub->overruns = 0;
+ }
+ vlc_cond_wait (&bank->wait, &bank->lock);
+ }
+
+ vlc_cleanup_pop ();
+ assert (0);