root/src/apps/cortex/NodeManager/NodeSyncThread.h
/*
 * Copyright (c) 1999-2000, Eric Moon.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions, and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


// NodeSyncThread.h [rewrite 14oct99]
// * PURPOSE
//   Provide continuous synchronization notices on
//   a particular BMediaNode.  Notification is sent
//   to a provided BMessenger.
//
//   As long as a NodeSyncThread object exists its thread
//   is running.  The thread blocks indefinitely, waiting
//   for a message to show up on an internal port.
//
//   Sync-notice requests (via the +++++ sync() operation)
//   trigger a message sent to that port.  The thread wakes
//   up, then calls BMediaRoster::SyncToNode() to wait
//   until a particular performace time arrives for that node.
//
//   If SyncToNode() times out, an M_TIMED_OUT message is sent;
//   otherwise, an M_SYNC_COMPLETE message is sent.
//
// * HISTORY
//   e.moon             14oct99         Rewrite begun.

#ifndef __NodeSyncThread_H__
#define __NodeSyncThread_H__

#include <MediaNode.h>
#include <Messenger.h>
#include <OS.h>

#include "cortex_defs.h"
__BEGIN_CORTEX_NAMESPACE

class NodeSyncThread {
public:                                                                                                 // *** messages
        enum message_t {
                // 'nodeID' (int32)         media_node_id value
                // 'perfTime' (int64)                           the performance time
                // 'position' (int64)       corresponding (caller-provided) position
                M_SYNC_COMPLETE                                                 =NodeSyncThread_message_base,
                
                // 'nodeID' (int32)         media_node_id value
                // 'error' (int32)                                      status_t value from SyncToNode()
                // 'perfTime' (int64)                           the performance time
                // 'position' (int64)       corresponding (caller-provided) position
                M_SYNC_FAILED
        };
        
public:                                                                                                 // *** dtor/ctors
        virtual ~NodeSyncThread();

        NodeSyncThread(
                const media_node&                                               node,
                BMessenger*                                                                     messenger);

public:                                                                                                 // *** operations
        // trigger a sync operation: when 'perfTime' arrives
        // for the node, a M_SYNC_COMPLETE message with the given
        // position value will be sent,  unless the sync operation
        // times out, in which case M_TIMED_OUT will be sent.
        status_t sync(
                bigtime_t                                                                               perfTime,
                bigtime_t                                                                               position,
                bigtime_t                                                                               timeout);

private:

        // the node to watch
        media_node                                                                              m_node;
        
        // the messenger to inform
        BMessenger*                                                                             m_messenger;

        // if the thread is running, it has exclusive write access
        // to this flag.
        volatile bool                                                                   m_syncInProgress;

        // thread guts
        thread_id                                                                                       m_thread;
        port_id                                                                                         m_port;
        char*                                                                                                   m_portBuffer;
        ssize_t                                                                                         m_portBufferSize;

        enum _op_codes {
                M_TRIGGER
        };

        struct _sync_op {
                bigtime_t       targetTime;
                bigtime_t               position;
                bigtime_t               timeout;
        };
        
        static status_t _Sync(
                void*                                                                                           cookie);
        void _sync();
};

__END_CORTEX_NAMESPACE
#endif /*__NodeSyncThread_H__*/