Rev 17 | Rev 23 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 17 | Rev 21 | ||
---|---|---|---|
Line 201... | Line 201... | ||
201 | }
|
201 | }
|
202 | 202 | ||
203 | 203 | ||
204 | void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException) |
204 | void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException) |
205 | {
|
205 | {
|
- | 206 | IN_WRITE_BEGIN |
|
- | 207 | ||
206 | if (m_wd != -1) { |
208 | if (m_wd != -1) { |
207 | int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask); |
209 | int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask); |
208 | if (wd != m_wd) |
210 | if (wd != m_wd) { |
- | 211 | IN_WRITE_END_NOTHROW |
|
209 | throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this); |
212 | throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this); |
- | 213 | }
|
|
210 | }
|
214 | }
|
211 | 215 | ||
212 | m_uMask = uMask; |
216 | m_uMask = uMask; |
- | 217 | ||
- | 218 | IN_WRITE_END |
|
213 | }
|
219 | }
|
214 | 220 | ||
215 | void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException) |
221 | void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException) |
216 | {
|
222 | {
|
- | 223 | IN_WRITE_BEGIN |
|
- | 224 | ||
217 | if (fEnabled == m_fEnabled) |
225 | if (fEnabled == m_fEnabled) { |
- | 226 | IN_WRITE_END_NOTHROW |
|
218 | return; |
227 | return; |
- | 228 | }
|
|
219 | 229 | ||
220 | if (m_pInotify != NULL) { |
230 | if (m_pInotify != NULL) { |
221 | if (fEnabled) { |
231 | if (fEnabled) { |
222 | m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask); |
232 | m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask); |
223 | if (m_wd == -1) |
233 | if (m_wd == -1) { |
- | 234 | IN_WRITE_END_NOTHROW |
|
224 | throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this); |
235 | throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this); |
- | 236 | }
|
|
225 | m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this)); |
237 | m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this)); |
226 | }
|
238 | }
|
227 | else { |
239 | else { |
228 | if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) |
240 | if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) { |
- | 241 | IN_WRITE_END_NOTHROW |
|
229 | throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this); |
242 | throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this); |
- | 243 | }
|
|
230 | m_pInotify->m_watches.erase(m_wd); |
244 | m_pInotify->m_watches.erase(m_wd); |
231 | m_wd = -1; |
245 | m_wd = -1; |
232 | }
|
246 | }
|
233 | }
|
247 | }
|
234 | 248 | ||
235 | m_fEnabled = fEnabled; |
249 | m_fEnabled = fEnabled; |
- | 250 | ||
- | 251 | IN_WRITE_END |
|
236 | }
|
252 | }
|
237 | 253 | ||
238 | 254 | ||
239 | Inotify::Inotify() throw (InotifyException) |
255 | Inotify::Inotify() throw (InotifyException) |
240 | {
|
256 | {
|
- | 257 | IN_LOCK_INIT |
|
- | 258 | ||
241 | m_fd = inotify_init(); |
259 | m_fd = inotify_init(); |
242 | if (m_fd == -1) |
260 | if (m_fd == -1) { |
- | 261 | IN_LOCK_DONE |
|
243 | throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL); |
262 | throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL); |
- | 263 | }
|
|
244 | }
|
264 | }
|
245 | 265 | ||
246 | Inotify::~Inotify() |
266 | Inotify::~Inotify() |
247 | {
|
267 | {
|
248 | Close(); |
268 | Close(); |
- | 269 | ||
- | 270 | IN_LOCK_DONE |
|
249 | }
|
271 | }
|
250 | 272 | ||
251 | void Inotify::Close() |
273 | void Inotify::Close() |
252 | {
|
274 | {
|
- | 275 | IN_WRITE_BEGIN |
|
- | 276 | ||
253 | if (m_fd != -1) { |
277 | if (m_fd != -1) { |
254 | RemoveAll(); |
278 | RemoveAll(); |
255 | close(m_fd); |
279 | close(m_fd); |
256 | m_fd = -1; |
280 | m_fd = -1; |
257 | }
|
281 | }
|
- | 282 | ||
- | 283 | IN_WRITE_END |
|
258 | }
|
284 | }
|
259 | 285 | ||
260 | void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException) |
286 | void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException) |
261 | {
|
287 | {
|
- | 288 | IN_WRITE_BEGIN |
|
- | 289 | ||
262 | // invalid descriptor - this case shouldn't occur - go away
|
290 | // invalid descriptor - this case shouldn't occur - go away
|
263 | if (m_fd == -1) |
291 | if (m_fd == -1) { |
- | 292 | IN_WRITE_END_NOTHROW |
|
264 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
293 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
- | 294 | }
|
|
265 | 295 | ||
266 | // this path already watched - go away
|
296 | // this path already watched - go away
|
267 | if (FindWatch(pWatch->GetPath()) != NULL) |
297 | if (FindWatch(pWatch->GetPath()) != NULL) { |
- | 298 | IN_WRITE_END_NOTHROW |
|
268 | throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this); |
299 | throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this); |
- | 300 | }
|
|
269 | 301 | ||
270 | // for enabled watch
|
302 | // for enabled watch
|
271 | if (pWatch->IsEnabled()) { |
303 | if (pWatch->IsEnabled()) { |
272 | 304 | ||
273 | // try to add watch to kernel
|
305 | // try to add watch to kernel
|
274 | int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask()); |
306 | int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask()); |
275 | 307 | ||
276 | // adding failed - go away
|
308 | // adding failed - go away
|
277 | if (wd == -1) |
309 | if (wd == -1) { |
- | 310 | IN_WRITE_END_NOTHROW |
|
278 | throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this); |
311 | throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this); |
- | 312 | }
|
|
279 | 313 | ||
280 | // this path already watched (but defined another way)
|
314 | // this path already watched (but defined another way)
|
281 | InotifyWatch* pW = FindWatch(wd); |
315 | InotifyWatch* pW = FindWatch(wd); |
282 | if (pW != NULL) { |
316 | if (pW != NULL) { |
283 | 317 | ||
284 | // try to recover old watch because it may be modified - then go away
|
318 | // try to recover old watch because it may be modified - then go away
|
285 | if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) { |
319 | if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) { |
- | 320 | IN_WRITE_END_NOTHROW |
|
286 | throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this); |
321 | throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this); |
287 | }
|
322 | }
|
288 | else { |
323 | else { |
289 | // recovery failed - go away
|
324 | // recovery failed - go away
|
- | 325 | IN_WRITE_END_NOTHROW |
|
290 | throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this); |
326 | throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this); |
291 | }
|
327 | }
|
292 | }
|
328 | }
|
293 | 329 | ||
294 | pWatch->m_wd = wd; |
330 | pWatch->m_wd = wd; |
295 | m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch)); |
331 | m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch)); |
296 | }
|
332 | }
|
297 | 333 | ||
298 | m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch)); |
334 | m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch)); |
299 | pWatch->m_pInotify = this; |
335 | pWatch->m_pInotify = this; |
- | 336 | ||
- | 337 | IN_WRITE_END |
|
300 | }
|
338 | }
|
301 | 339 | ||
302 | void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException) |
340 | void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException) |
303 | {
|
341 | {
|
- | 342 | IN_WRITE_BEGIN |
|
- | 343 | ||
304 | // invalid descriptor - this case shouldn't occur - go away
|
344 | // invalid descriptor - this case shouldn't occur - go away
|
305 | if (m_fd == -1) |
345 | if (m_fd == -1) { |
- | 346 | IN_WRITE_END_NOTHROW |
|
306 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
347 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
- | 348 | }
|
|
307 | 349 | ||
308 | // for enabled watch
|
350 | // for enabled watch
|
309 | if (pWatch->m_wd != -1) { |
351 | if (pWatch->m_wd != -1) { |
310 | 352 | ||
311 | // removing watch failed - go away
|
353 | // removing watch failed - go away
|
312 | if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) |
354 | if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) { |
- | 355 | IN_WRITE_END_NOTHROW |
|
313 | throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this); |
356 | throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this); |
- | 357 | }
|
|
314 | m_watches.erase(pWatch->m_wd); |
358 | m_watches.erase(pWatch->m_wd); |
315 | pWatch->m_wd = -1; |
359 | pWatch->m_wd = -1; |
316 | }
|
360 | }
|
317 | 361 | ||
318 | m_paths.erase(pWatch->m_path); |
362 | m_paths.erase(pWatch->m_path); |
319 | pWatch->m_pInotify = NULL; |
363 | pWatch->m_pInotify = NULL; |
- | 364 | ||
- | 365 | IN_WRITE_END |
|
320 | }
|
366 | }
|
321 | 367 | ||
322 | void Inotify::RemoveAll() |
368 | void Inotify::RemoveAll() |
323 | {
|
369 | {
|
- | 370 | IN_WRITE_BEGIN |
|
- | 371 | ||
324 | IN_WP_MAP::iterator it = m_paths.begin(); |
372 | IN_WP_MAP::iterator it = m_paths.begin(); |
325 | while (it != m_paths.end()) { |
373 | while (it != m_paths.end()) { |
326 | InotifyWatch* pW = (*it).second; |
374 | InotifyWatch* pW = (*it).second; |
327 | if (pW->m_wd != -1) { |
375 | if (pW->m_wd != -1) { |
328 | inotify_rm_watch(m_fd, pW->m_wd); |
376 | inotify_rm_watch(m_fd, pW->m_wd); |
Line 332... | Line 380... | ||
332 | it++; |
380 | it++; |
333 | }
|
381 | }
|
334 | 382 | ||
335 | m_watches.clear(); |
383 | m_watches.clear(); |
336 | m_paths.clear(); |
384 | m_paths.clear(); |
- | 385 | ||
- | 386 | IN_WRITE_END |
|
337 | }
|
387 | }
|
338 | 388 | ||
339 | void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException) |
389 | void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException) |
340 | {
|
390 | {
|
341 | ssize_t len = 0; |
391 | ssize_t len = 0; |
Line 348... | Line 398... | ||
348 | return; |
398 | return; |
349 | 399 | ||
350 | if (len < 0) |
400 | if (len < 0) |
351 | throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this); |
401 | throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this); |
352 | 402 | ||
- | 403 | IN_WRITE_BEGIN |
|
- | 404 | ||
353 | ssize_t i = 0; |
405 | ssize_t i = 0; |
354 | while (i < len) { |
406 | while (i < len) { |
355 | struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i]; |
407 | struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i]; |
356 | InotifyWatch* pW = FindWatch(pEvt->wd); |
408 | InotifyWatch* pW = FindWatch(pEvt->wd); |
357 | if (pW != NULL) { |
409 | if (pW != NULL) { |
358 | InotifyEvent evt(pEvt, pW); |
410 | InotifyEvent evt(pEvt, pW); |
359 | m_events.push_back(evt); |
411 | m_events.push_back(evt); |
360 | }
|
412 | }
|
361 | i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
413 | i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
362 | }
|
414 | }
|
363 | }
|
- | |
364 | 415 | ||
365 | int Inotify::GetEventCount() |
- | |
366 | {
|
- | |
367 | return m_events.size(); |
416 | IN_WRITE_END |
368 | }
|
417 | }
|
369 | 418 | ||
370 | bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException) |
419 | bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException) |
371 | {
|
420 | {
|
372 | bool b = PeekEvent(pEvt); |
421 | if (pEvt == NULL) |
- | 422 | throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this); |
|
- | 423 | ||
- | 424 | IN_WRITE_BEGIN |
|
373 | 425 | ||
- | 426 | bool b = !m_events.empty(); |
|
374 | if (b) |
427 | if (b) { |
- | 428 | *pEvt = m_events.front(); |
|
375 | m_events.pop_front(); |
429 | m_events.pop_front(); |
- | 430 | }
|
|
- | 431 | ||
- | 432 | IN_WRITE_END |
|
376 | 433 | ||
377 | return b; |
434 | return b; |
378 | }
|
435 | }
|
379 | 436 | ||
380 | bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException) |
437 | bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException) |
381 | {
|
438 | {
|
382 | if (pEvt == NULL) |
439 | if (pEvt == NULL) |
383 | throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this); |
440 | throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this); |
384 | 441 | ||
- | 442 | IN_READ_BEGIN |
|
- | 443 | ||
385 | if (!m_events.empty()) { |
444 | bool b = !m_events.empty(); |
- | 445 | if (b) { |
|
386 | *pEvt = m_events.front(); |
446 | *pEvt = m_events.front(); |
387 | return true; |
- | |
388 | }
|
447 | }
|
389 | 448 | ||
- | 449 | IN_READ_END |
|
- | 450 | ||
390 | return false; |
451 | return b; |
391 | }
|
452 | }
|
392 | 453 | ||
393 | InotifyWatch* Inotify::FindWatch(int iDescriptor) |
454 | InotifyWatch* Inotify::FindWatch(int iDescriptor) |
394 | {
|
455 | {
|
- | 456 | IN_READ_BEGIN |
|
- | 457 | ||
395 | IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor); |
458 | IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor); |
396 | if (it == m_watches.end()) |
459 | InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second; |
- | 460 | ||
397 | return NULL; |
461 | IN_READ_END |
398 | 462 | ||
399 | return (*it).second; |
463 | return pW; |
400 | }
|
464 | }
|
401 | 465 | ||
402 | InotifyWatch* Inotify::FindWatch(const std::string& rPath) |
466 | InotifyWatch* Inotify::FindWatch(const std::string& rPath) |
403 | {
|
467 | {
|
- | 468 | IN_READ_BEGIN |
|
- | 469 | ||
404 | IN_WP_MAP::iterator it = m_paths.find(rPath); |
470 | IN_WP_MAP::iterator it = m_paths.find(rPath); |
405 | if (it == m_paths.end()) |
471 | InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second; |
- | 472 | ||
406 | return NULL; |
473 | IN_READ_END |
407 | 474 | ||
408 | return (*it).second; |
475 | return pW; |
409 | }
|
476 | }
|
410 | 477 | ||
411 | void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException) |
478 | void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException) |
412 | {
|
479 | {
|
- | 480 | IN_WRITE_BEGIN |
|
- | 481 | ||
413 | if (m_fd == -1) |
482 | if (m_fd == -1) { |
- | 483 | IN_WRITE_END_NOTHROW |
|
414 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
484 | throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this); |
- | 485 | }
|
|
415 | 486 | ||
416 | int res = fcntl(m_fd, F_GETFL); |
487 | int res = fcntl(m_fd, F_GETFL); |
417 | if (res == -1) |
488 | if (res == -1) { |
- | 489 | IN_WRITE_END_NOTHROW |
|
418 | throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this); |
490 | throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this); |
- | 491 | }
|
|
419 | 492 | ||
420 | if (fNonBlock) { |
493 | if (fNonBlock) { |
421 | res |= O_NONBLOCK; |
494 | res |= O_NONBLOCK; |
422 | }
|
495 | }
|
423 | else { |
496 | else { |
424 | res &= ~O_NONBLOCK; |
497 | res &= ~O_NONBLOCK; |
425 | }
|
498 | }
|
426 | 499 | ||
427 | if (fcntl(m_fd, F_SETFL, res) == -1) |
500 | if (fcntl(m_fd, F_SETFL, res) == -1) { |
- | 501 | IN_WRITE_END_NOTHROW |
|
428 | throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this); |
502 | throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this); |
- | 503 | }
|
|
- | 504 | ||
- | 505 | IN_WRITE_END |
|
429 | }
|
506 | }
|
430 | 507 |