vfs: check userland buffers before reading them.
[haiku.git] / src / apps / cortex / NodeManager / NodeSyncThread.cpp
blob66e2f8f9e194d64e9e86d111b36e09d9a93a3fc0
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // NodeSyncThread.cpp
34 #include "NodeSyncThread.h"
36 #include <cstring>
38 #include <Debug.h>
39 #include <MediaRoster.h>
41 __USE_CORTEX_NAMESPACE
43 // -------------------------------------------------------- //
44 // *** dtor/ctors
45 // -------------------------------------------------------- //
47 NodeSyncThread::~NodeSyncThread() {
48 status_t err;
50 // clean up
51 if(m_thread) {
52 err = kill_thread(m_thread);
53 if(err < B_OK)
54 PRINT((
55 "! ~NodeSyncThread(): kill_thread(%" B_PRId32 "):\n"
56 " %s\n",
57 m_thread,
58 strerror(err)));
60 // +++++ is a wait_for_thread() necessary?
63 if(m_port) {
64 err = delete_port(m_port);
65 if(err < B_OK)
66 PRINT((
67 "! ~NodeSyncThread(): delete_port(%" B_PRId32 "):\n"
68 " %s\n",
69 m_port,
70 strerror(err)));
73 if(m_portBuffer)
74 delete [] m_portBuffer;
75 if(m_messenger)
76 delete m_messenger;
79 NodeSyncThread::NodeSyncThread(
80 const media_node& node,
81 BMessenger* messenger) :
83 m_node(node),
84 m_messenger(messenger),
85 m_syncInProgress(false),
86 m_thread(0),
87 m_port(0),
88 m_portBuffer(0),
89 m_portBufferSize(sizeof(_sync_op)) {
91 ASSERT(m_messenger);
93 m_portBuffer = new char[m_portBufferSize];
95 m_port = create_port(
96 m_portBufferSize * 16,
97 "NodeSyncThread___port");
98 ASSERT(m_port >= B_OK);
100 m_thread = spawn_thread(
101 &_Sync,
102 "NodeSyncThread",
103 B_DISPLAY_PRIORITY,
104 this);
105 ASSERT(m_thread >= B_OK);
106 resume_thread(m_thread);
109 // -------------------------------------------------------- //
110 // *** operations
111 // -------------------------------------------------------- //
113 // trigger a sync operation: when 'perfTime' arrives
114 // for the node, a M_SYNC_COMPLETE message with the given
115 // position value will be sent, unless the sync operation
116 // times out, in which case M_TIMED_OUT will be sent.
118 status_t NodeSyncThread::sync(
119 bigtime_t perfTime,
120 bigtime_t position,
121 bigtime_t timeout) {
123 status_t err;
125 if(m_syncInProgress)
126 return B_NOT_ALLOWED;
128 _sync_op op = {perfTime, position, timeout};
129 err = write_port(
130 m_port,
131 M_TRIGGER,
132 &op,
133 sizeof(_sync_op));
135 return err;
138 // -------------------------------------------------------- //
139 // *** guts
140 // -------------------------------------------------------- //
142 /*static*/
143 status_t NodeSyncThread::_Sync(
144 void* cookie) {
145 ((NodeSyncThread*)cookie)->_sync();
146 return B_OK;
149 // THREAD BODY
151 void NodeSyncThread::_sync() {
152 ASSERT(m_port >= B_OK);
153 ASSERT(m_messenger);
155 bool done = false;
156 while(!done) {
158 // WAIT FOR A REQUEST
159 int32 code;
160 ssize_t readCount = read_port(
161 m_port,
162 &code,
163 m_portBuffer,
164 m_portBufferSize);
166 if(readCount < B_OK) {
167 PRINT((
168 "! NodeSyncThread::_sync(): read_port():\n"
169 " %s\n",
170 strerror(readCount)));
171 continue;
174 if(code != M_TRIGGER) {
175 PRINT((
176 "! NodeSyncThread::sync(): unknown message code %" B_PRId32
177 "\n", code));
178 continue;
181 // SERVICE THE REQUEST
182 const _sync_op& op = *(_sync_op*)m_portBuffer;
184 // pre-fill the message
185 BMessage m(M_SYNC_COMPLETE);
186 m.AddInt32("nodeID", m_node.node);
187 m.AddInt64("perfTime", op.targetTime);
188 m.AddInt64("position", op.position);
190 // sync
191 status_t err = BMediaRoster::Roster()->SyncToNode(
192 m_node,
193 op.targetTime,
194 op.timeout);
196 // deliver reply
197 if(err < B_OK) {
198 m.what = M_SYNC_FAILED;
199 m.AddInt32("error", err);
202 err = m_messenger->SendMessage(&m);
203 if(err < B_OK) {
204 PRINT((
205 "! NodeSyncThread::_sync(): m_messenger->SendMessage():\n"
206 " %s\n",
207 strerror(err)));
213 // END -- NodeSyncThread.cpp --