summaryrefslogtreecommitdiff
path: root/x11/ipc
authorzecke <zecke>2002-10-18 01:34:23 (UTC)
committer zecke <zecke>2002-10-18 01:34:23 (UTC)
commit0457c48c165abef8afa2ac73c8f66d20e289681a (patch) (unidiff)
tree2c6baf363487d474df6ceeaf2ea17a351b38aa05 /x11/ipc
parente7e36afd3685c7fab146ebd0078d7f1a60f8c5e6 (diff)
downloadopie-0457c48c165abef8afa2ac73c8f66d20e289681a.zip
opie-0457c48c165abef8afa2ac73c8f66d20e289681a.tar.gz
opie-0457c48c165abef8afa2ac73c8f66d20e289681a.tar.bz2
Fix OCOPServer bugs... when removing clients
Implement the Opie side for the OK button now the awesome matchbox needs to get an update I was too excited about X11 so i did not do any PIM work yet
Diffstat (limited to 'x11/ipc') (more/less context) (ignore whitespace changes)
-rw-r--r--x11/ipc/server/ocopserver.cpp59
1 files changed, 35 insertions, 24 deletions
diff --git a/x11/ipc/server/ocopserver.cpp b/x11/ipc/server/ocopserver.cpp
index 4940cb8..0f818b7 100644
--- a/x11/ipc/server/ocopserver.cpp
+++ b/x11/ipc/server/ocopserver.cpp
@@ -103,297 +103,308 @@ void OCopServer::initSocket() {
103} 103}
104/** 104/**
105 * we got the possibility to read 105 * we got the possibility to read
106 * on the server 106 * on the server
107 * this is mostly due a connect 107 * this is mostly due a connect
108 * on a client side 108 * on a client side
109 * we will accept it 109 * we will accept it
110 * add it to our list 110 * add it to our list
111 */ 111 */
112void OCopServer::newOnServer() { 112void OCopServer::newOnServer() {
113 int fd = accept(); 113 int fd = accept();
114 if ( fd < 0 ) 114 if ( fd < 0 )
115 return; 115 return;
116 116
117 /* 117 /*
118 * we got a successfull new connection 118 * we got a successfull new connection
119 * be happy 119 * be happy
120 * set SocketNotifier 120 * set SocketNotifier
121 * connect it 121 * connect it
122 * and a OCOPClient 122 * and a OCOPClient
123 */ 123 */
124 qWarning("Heureka new connection %d", fd ); 124 qWarning("Heureka new connection %d", fd );
125 125
126 126
127 registerClient( fd ); 127 registerClient( fd );
128} 128}
129int OCopServer::accept() { 129int OCopServer::accept() {
130 /* 130 /*
131 * accept it 131 * accept it
132 * the socket is currently blocking IIRC 132 * the socket is currently blocking IIRC
133 */ 133 */
134 return ::accept( m_serverfd, (struct sockaddr*)&m_address, &m_adrlaenge ); 134 return ::accept( m_serverfd, (struct sockaddr*)&m_address, &m_adrlaenge );
135} 135}
136void OCopServer::newOnClient( int fd ) { 136void OCopServer::newOnClient( int fd ) {
137 errno = 0; 137 errno = 0;
138 OCOPHead head; 138 OCOPHead head;
139 memset(&head, 0, sizeof(head) ); 139 memset(&head, 0, sizeof(head) );
140 int rea = ::read(fd, &head, sizeof(head) ); 140 int rea = ::read(fd, &head, sizeof(head) );
141 //qWarning("read %d %d", rea, errno); 141 //qWarning("read %d %d", rea, errno);
142 /* 142 /*
143 * I should get EPIPE but nothing like this happens 143 * I should get EPIPE but nothing like this happens
144 * so if rea == 0 and we were signaled by the notifier 144 * so if rea == 0 and we were signaled by the notifier
145 * we close it and drop the clients... 145 * we close it and drop the clients...
146 */ 146 */
147 if ( rea <= 0 ) { 147 if ( rea <= 0 ) {
148 deregisterClient( fd ); 148 deregisterClient( fd );
149 return; 149 return;
150 } 150 }
151 /* 151 /*
152 * OCOPHead 152 * OCOPHead
153 */ 153 */
154 //qWarning("data %s %d", &bug, rea ); 154 //qWarning("data %s %d", &bug, rea );
155 155
156 /* 156 /*
157 * Check the magic 157 * Check the magic
158 * if chcked read till EOF if magic does not match 158 * if chcked read till EOF if magic does not match
159 * otherwise do read 159 * otherwise do read
160 * channel 160 * channel
161 * func 161 * func
162 * data into mem 162 * data into mem
163 * and then send the OCOPPacket 163 * and then send the OCOPPacket
164 * 164 *
165 */ 165 */
166 if (head.magic == 47 ) { 166 if (head.magic == 47 ) {
167 qWarning("magic match"); 167// qWarning("magic match");
168 QCString channel( head.chlen+1 ); 168 QCString channel( head.chlen+1 );
169 QCString func( head.funclen+1 ); 169 QCString func( head.funclen+1 );
170 QByteArray data ( head.datalen ); 170 QByteArray data ( head.datalen );
171 171
172 /* 172 /*
173 * we do not check for errors 173 * we do not check for errors
174 */ 174 */
175 qWarning("read "); 175// qWarning("read ");
176 int s = read(fd, channel.data(), head.chlen ); 176 int s = read(fd, channel.data(), head.chlen );
177 s = read(fd, func.data(), head.funclen ); 177 s = read(fd, func.data(), head.funclen );
178 s = read(fd, data.data(), head.datalen ); 178 s = read(fd, data.data(), head.datalen );
179 qWarning("read"); 179// qWarning("read");
180 180
181 /* debug output */ 181 /* debug output */
182 qWarning("channel %s %d", channel.data(), head.chlen ); 182// qWarning("channel %s %d", channel.data(), head.chlen );
183 qWarning("func %s %d", func.data(), head.funclen ); 183// qWarning("func %s %d", func.data(), head.funclen );
184 /* debug end */ 184 /* debug end */
185 185
186 /* 186 /*
187 * now that we got the complete body 187 * now that we got the complete body
188 * we need to make a package 188 * we need to make a package
189 * and then we need to send it to clients 189 * and then we need to send it to clients
190 * making a package is done here 190 * making a package is done here
191 * dispatching it not 191 * dispatching it not
192 */ 192 */
193 OCOPPacket packet( head.type, channel, func, data ); 193 OCOPPacket packet( head.type, channel, func, data );
194 dispatch( packet, fd ); 194 dispatch( packet, fd );
195 195
196 }else{ 196 }else{
197 qWarning("magic does not match"); 197 qWarning("magic does not match");
198 qWarning("magic %d", head.magic ); 198 qWarning("magic %d", head.magic );
199 } 199 }
200} 200}
201void OCopServer::registerClient( int fd ) { 201void OCopServer::registerClient( int fd ) {
202 if (m_clients.contains(fd) ) 202 if (m_clients.contains(fd) )
203 return; 203 return;
204 204
205 QSocketNotifier* notify = new QSocketNotifier(fd, QSocketNotifier::Read, this ); 205 QSocketNotifier* notify = new QSocketNotifier(fd, QSocketNotifier::Read, this );
206 connect(notify, SIGNAL(activated(int) ), 206 connect(notify, SIGNAL(activated(int) ),
207 this, SLOT(newOnClient(int) ) ); 207 this, SLOT(newOnClient(int) ) );
208 OCOPClient client; 208 OCOPClient client;
209 client.fd = fd; 209 client.fd = fd;
210 client.notify = notify; 210 client.notify = notify;
211 m_clients.insert( client.fd, client ); 211 m_clients.insert( client.fd, client );
212 qWarning("clients are up to %d", m_clients.count() ); 212 qWarning("clients are up to %d", m_clients.count() );
213}; 213};
214void OCopServer::deregisterClient(int fd ) { 214void OCopServer::deregisterClient(int fd ) {
215 QMap<int, OCOPClient>::Iterator it = m_clients.find( fd ); 215 QMap<int, OCOPClient>::Iterator it = m_clients.find( fd );
216 if (it != m_clients.end() ) { 216 if (it != m_clients.end() ) {
217 OCOPClient client = it.data();
218 delete client.notify;
219 m_clients.remove(fd );
220 close(fd );
221 /* 217 /*
222 * TIME_ME 218 * TIME_ME
223 * 219 *
224 * now delete from all channels 220 * now delete from all channels
225 * go through all channels 221 * go through all channels
226 * remove the fd from the list 222 * remove the fd from the list
227 * if count becomes 0 remove the channel 223 * if count becomes 0 remove the channel
228 * otherwise replace QArray<int> 224 * otherwise replace QArray<int>
229 */ 225 */
230 QMap<QCString, QValueList<int> >::Iterator it2; 226 QMap<QCString, QValueList<int> >::Iterator it2;
231 repeatIt: 227 repeatIt:
232 for ( it2 = m_channels.begin(); it2 != m_channels.end(); ++it2 ) { 228 for ( it2 = m_channels.begin(); it2 != m_channels.end(); ++it2 ) {
233 /* 229 /*
234 * The channel contains this fd 230 * The channel contains this fd
235 */ 231 */
236 qWarning("Channel %s", it2.key().data() ); 232 qWarning("Channel %s %d", it2.key().data(), it2.data().count() );
237 if ( it2.data().contains( fd ) ) { 233 if ( it2.data().contains( fd ) ) {
238 qWarning("contains"); 234 qWarning("contains");
239 QValueList<int> array = it2.data(); 235 QValueList<int> array = it2.data();
240 236
241 /* 237 /*
242 * remove channel or just replace 238 * remove channel or just replace
243 */ 239 */
244 if ( array.count() == 1 ) { 240 if ( array.count() == 1 || array.count() == 0) {
245 qWarning("Invalidate!"); 241 qWarning("Invalidate!");
246 /* is the list now invalidatet? */ 242 /* is the list now invalidatet? */
247 m_channels.remove( it2 ); 243 m_channels.remove( it2 );
248 /* That is the first go to of my life 244 /* That is the first go to of my life
249 * but Iterator remove( Iterator ) 245 * but Iterator remove( Iterator )
250 * does not exist 246 * does not exist
251 * it2 = --it2; 247 * it2 = --it2;
252 * does not work reliable too 248 * does not work reliable too
253 * so the only way is to reiterate :( 249 * so the only way is to reiterate :(
254 */ 250 */
255 goto repeatIt; 251 goto repeatIt;
256 }else{ 252 }else{
257 qWarning("removing"); 253 qWarning("removing count %d %d",fd, array.count() );
258 array.remove( fd ); 254 QValueList<int>::Iterator it3 = array.find( fd );
259 it2 = m_channels.replace( it2.key(), array ); 255 it3 = array.remove( it3 );
256 QCString key = it2.key().copy();
257 it2 = m_channels.replace( key, array );
260 } 258 }
261 } 259 }
262 } // off all channels 260 } // off all channels
261 OCOPClient client = it.data();
262 delete client.notify;
263 m_clients.remove(fd );
264 close(fd );
263 } 265 }
264 qWarning("clients are now at %d", m_clients.count() ); 266 qWarning("clients are now at %d", m_clients.count() );
265}; 267};
266/** 268/**
267 * this function will evaluate 269 * this function will evaluate
268 * the package and then do the appropriate thins 270 * the package and then do the appropriate thins
269 */ 271 */
270void OCopServer::dispatch( const OCOPPacket& packet, int sourceFD ) { 272void OCopServer::dispatch( const OCOPPacket& packet, int sourceFD ) {
271 qWarning("packet.type() == %d", packet.type() ); 273 qWarning("packet.type() == %d", packet.type() );
272 switch( packet.type() ) { 274 switch( packet.type() ) {
273 case OCOPPacket::Register: 275 case OCOPPacket::Register:
274 registerClient(sourceFD ); 276 registerClient(sourceFD );
275 break; 277 break;
276 case OCOPPacket::Unregister: 278 case OCOPPacket::Unregister:
277 deregisterClient(sourceFD ); 279 deregisterClient(sourceFD );
278 break; 280 break;
279 case OCOPPacket::Call: 281 case OCOPPacket::Call:
280 call( packet, sourceFD ); 282 call( packet, sourceFD );
281 break; 283 break;
282 /* not implemented */ 284 /* not implemented */
283 case OCOPPacket::Method: 285 case OCOPPacket::Method:
284 break; 286 break;
285 /* nit implemented */ 287 /* nit implemented */
286 case OCOPPacket::Reply: 288 case OCOPPacket::Reply:
287 break; 289 break;
288 case OCOPPacket::RegisterChannel: 290 case OCOPPacket::RegisterChannel:
289 addChannel( packet.channel() , sourceFD ); 291 addChannel( packet.channel() , sourceFD );
290 break; 292 break;
291 case OCOPPacket::UnregisterChannel: 293 case OCOPPacket::UnregisterChannel:
292 delChannel( packet.channel(), sourceFD ); 294 delChannel( packet.channel(), sourceFD );
293 break; 295 break;
294 /* not implemented */ 296 /* not implemented */
295 case OCOPPacket::Return: 297 case OCOPPacket::Return:
296 break; 298 break;
297 /* not implemented :( */ 299 /* not implemented :( */
298 case OCOPPacket::Signal: 300 case OCOPPacket::Signal:
299 break; 301 break;
300 case OCOPPacket::IsRegistered: 302 case OCOPPacket::IsRegistered:
301 qWarning("IsRegistered"); 303 qWarning("IsRegistered");
302 isRegistered( packet.channel(), sourceFD ); 304 isRegistered( packet.channel(), sourceFD );
303 break; 305 break;
304 }; 306 };
305} 307}
306void OCopServer::errorOnServer() { 308void OCopServer::errorOnServer() {
307 /* 309 /*
308 * something is wrong on the server socket? 310 * something is wrong on the server socket?
309 * what should we do? 311 * what should we do?
310 * FIXME 312 * FIXME
311 */ 313 */
312} 314}
313QStringList OCopServer::channels() { 315QStringList OCopServer::channels() {
314 QStringList list; 316 QStringList list;
315 { 317 {
316 QMap<QCString, QValueList<int> >::Iterator it; 318 QMap<QCString, QValueList<int> >::Iterator it;
317 for (it = m_channels.begin(); it != m_channels.end(); ++it ) { 319 for (it = m_channels.begin(); it != m_channels.end(); ++it ) {
318 list << it.key(); 320 list << it.key();
319 }; 321 };
320 } 322 }
321 return list; 323 return list;
322} 324}
323bool OCopServer::isChannelRegistered( const QCString& chan ) const{ 325bool OCopServer::isChannelRegistered( const QCString& chan ) const{
324 return m_channels.contains( chan ); 326 return m_channels.contains( chan );
325} 327}
326void OCopServer::addChannel( const QCString& channel, 328void OCopServer::addChannel( const QCString& channel,
327 int fd ) { 329 int fd ) {
328 QMap<QCString, QValueList<int> >::Iterator it; 330 QMap<QCString, QValueList<int> >::Iterator it;
329 it = m_channels.find( channel ); 331 it = m_channels.find( channel );
330 332 if ( it != m_channels.end() ) {
331 /* could be empty */ 333 /* could be empty */
332 QValueList<int> list = it.data(); 334 QValueList<int> list = it.data();
333 list.append( fd ); 335 list.append( fd );
334 it = m_channels.replace( channel, list ); 336 qWarning("count is now in addChannel %d %s", list.count(), channel.data() );
337 it = m_channels.replace( channel, list );
338 }else {
339 QValueList<int> ints;
340 ints.append( fd );
341 m_channels.insert( channel, ints );
342 }
335}; 343};
336void OCopServer::delChannel( const QCString& channel, 344void OCopServer::delChannel( const QCString& channel,
337 int fd ) { 345 int fd ) {
346 qWarning("remove %s, %d", channel.data(), fd );
338 if (!m_channels.contains( channel ) ) 347 if (!m_channels.contains( channel ) )
339 return; 348 return;
340 349
341 QMap<QCString, QValueList<int> >::Iterator it; 350 QMap<QCString, QValueList<int> >::Iterator it;
342 it = m_channels.find( channel ); 351 it = m_channels.find( channel );
343 352
344 if ( it.data().contains(fd) ) { 353 if ( it.data().contains(fd) ) {
345
346 QValueList<int> ints = it.data(); 354 QValueList<int> ints = it.data();
347 if ( ints.count() == 1 ) 355 if ( ints.count() == 1 )
348 m_channels.remove( it ); 356 m_channels.remove( channel );
349 else{ 357 else{
350 QValueList<int> ints = it.data(); 358 QValueList<int> ints = it.data();
351 ints.remove( fd ); 359 QValueList<int>::Iterator rem = ints.find( fd );
352 m_channels.replace( it.key(), ints ); 360 rem = ints.remove( rem );
361 QCString str = it.key().copy();
362 m_channels.replace( str, ints );
353 } 363 }
364 qWarning(" channel count is now %d", ints.count() );
354 } 365 }
355} 366}
356void OCopServer::isRegistered( const QCString& channel, int fd) { 367void OCopServer::isRegistered( const QCString& channel, int fd) {
357 qWarning("isRegistered"); 368// qWarning("isRegistered");
358 OCOPHead head; 369 OCOPHead head;
359 QCString func(2); 370 QCString func(2);
360 371
361 memset(&head, 0, sizeof(head ) ); 372 memset(&head, 0, sizeof(head ) );
362 head.magic = 47; 373 head.magic = 47;
363 head.type = OCOPPacket::IsRegistered; 374 head.type = OCOPPacket::IsRegistered;
364 head.chlen = channel.size(); 375 head.chlen = channel.size();
365 head.funclen = func.size(); 376 head.funclen = func.size();
366 head.datalen = 0; 377 head.datalen = 0;
367 378
368 if ( isChannelRegistered( channel ) ) { 379 if ( isChannelRegistered( channel ) ) {
369 //is registered 380 //is registered
370 func[0] = 1; 381 func[0] = 1;
371 }else{ 382 }else{
372 func[0] = 0; 383 func[0] = 0;
373 } 384 }
374 385
375 /** 386 /**
376 * write the head 387 * write the head
377 * and then channel 388 * and then channel
378 * success/failure inside func 389 * success/failure inside func
379 */ 390 */
380 write(fd, &head, sizeof(head) ); 391 write(fd, &head, sizeof(head) );
381 write(fd, channel.data(), channel.size() ); 392 write(fd, channel.data(), channel.size() );
382 write(fd, func.data(), func.size() ); 393 write(fd, func.data(), func.size() );
383} 394}
384QValueList<int> OCopServer::clients( const QCString& channel ) { 395QValueList<int> OCopServer::clients( const QCString& channel ) {
385 return m_channels[channel]; 396 return m_channels[channel];
386} 397}
387void OCopServer::call( const OCOPPacket& p, int ) { 398void OCopServer::call( const OCOPPacket& p, int ) {
388 QValueList<int> cli = clients( p.channel() ); 399 QValueList<int> cli = clients( p.channel() );
389 QValueList<int>::Iterator it; 400 QValueList<int>::Iterator it;
390 401
391 OCOPHead head = p.head(); 402 OCOPHead head = p.head();
392 for (it = cli.begin(); it != cli.end(); ++it ) { 403 for (it = cli.begin(); it != cli.end(); ++it ) {
393 write( (*it), &head, sizeof(head ) ); 404 write( (*it), &head, sizeof(head ) );
394 /* expl. shared! */ 405 /* expl. shared! */
395 write( (*it), p.channel().data(), p.channel().size() ); 406 write( (*it), p.channel().data(), p.channel().size() );
396 write( (*it), p.header().data(), p.header().size() ); 407 write( (*it), p.header().data(), p.header().size() );
397 write( (*it), p.content().data(), p.content().size() ); 408 write( (*it), p.content().data(), p.content().size() );
398 }; 409 };
399} 410}