web developer & system programmer

coder . cl

ramblings and thoughts on programming...


wowza synchronization and required mutexes

published: 11-01-2011 / updated: 11-01-2011
posted in: development, java, programming, projects, tips
by Daniel Molina Wegener

As we have seen Wowza Media Server supports custom extensions through its Java API. One big deal with the Wowza Media Server, while I was creating the time shifted streaming extension, was the server thread synchronization. Not a big deal from the point of view regarding the client side stream, but the monitoring thread for each recorder and playlist was a problem to synchronize. Most problems were related to interface implementations.


list implementation

As we have seen, the playlist container uses a List implementation to store PlaylistItem objects. The problem with that implementation is that you can’t execute the clear() method properly, because it maintains the list size. So, each time that I was adding items to the playlist, and every time that a reschedule was required I was using the addToPlaylist() method before the clear() call, expecting the list to be emptied and resized to zero. That was not true. The trick was just to create a new playlist on each reschedule event.

Playlist playlist = new Playlist(stream.getName());
playlistMap.put(stream.getName(), playlist);
long offset = WowzaTools.getTimeShiftOffset(videoList, minutesToShift);
synchronized (streamMutex) {
    for (int pi = 0; pi < videoList.length; pi++) {
        VideoInfo cs = videoList[pi];
        if (pi == 0) {
            stream.addToPlaylist(stream.getPlaylist().size() + 1,
                                 cs.getVideo().getName(),
                                 (int) offset, cs.getDuration());
        } else {
            stream.addToPlaylist(stream.getPlaylist().size() + 1,
                                 cs.getVideo().getName(),
                                 0, cs.getDuration());
        }
    }
}
playlist.open(stream);


required mutexes

When the stream recording cuts the stream recording twice — caused by network problems — the onPlaylistItemStop() is triggered twice too. This can cause a race condition, and causing the server to stop some stream transmissions, and even can cause the lost of the stream recording. Events are not triggered sequentially, and they seems to be using some asynchronous kind of execution mechanism. So, the playlist rescheduling mechanism has to deal with that condition. To solve that issue, I’ve created two mutexes. One mutex for the event scheduler and other mutex for the stream treating mechanism. That is ensuring — in some manner — that event handlers are executed sequentially.

synchronized (schedulerMutex) {
    if (item.getIndex() == (stream.getPlaylist().size() - 1)) {
        synchronized (streamMutex) {
            setupStream(stream);
        }
    }
}

The previous algorithm ensures scheduler events are triggered sequentially and even stream treating methods are treating the streams blocking them on each event. Why I don’t used the stream itself as mutex, is because the stream can be blocked by other threads, and probably it can cause a deadlock, so I don’t have blocked server side objects. Probably, instead of using a synchronized mutex on Java for certain cases is less elegant than using rwlocks in POSIX threads, but the Java API do not offers rwlocks, and you can deal only with synchronized mutexes. I’ve missed rwlocks in this project.


No coments yet.

post a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>