async.cc 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /********************************************************************** <BR>
  2. This file is part of Crack dot Com's free source code release of
  3. Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
  4. information about compiling & licensing issues visit this URL</a>
  5. <PRE> If that doesn't help, contact Jonathan Clark at
  6. golgotha_source@usa.net (Subject should have "GOLG" in it)
  7. ***********************************************************************/
  8. #include "file/async.hh"
  9. #include "threads/threads.hh"
  10. #include "time/time.hh"
  11. #include "error/error.hh"
  12. i4_async_reader::i4_async_reader(char *name) : sig(name)
  13. {
  14. emulation=i4_F;
  15. stop=i4_F;
  16. }
  17. void i4_async_reader_thread_start(void *arg)
  18. {
  19. ((i4_async_reader *)arg)->PRIVATE_thread();
  20. }
  21. void i4_async_reader::init()
  22. {
  23. if (i4_threads_supported())
  24. {
  25. stop=i4_T;
  26. i4_add_thread(i4_async_reader_thread_start, STACK_SIZE, this);
  27. }
  28. }
  29. void i4_async_reader::uninit()
  30. {
  31. if (i4_threads_supported())
  32. {
  33. while (stop==i4_T) // wait to thread is read to be stopped
  34. i4_thread_yield();
  35. stop=i4_T;
  36. sig.signal();
  37. while (stop)
  38. i4_thread_yield();
  39. }
  40. }
  41. i4_bool i4_async_reader::start_read(int fd, void *buffer, w32 size,
  42. i4_file_class::async_callback call,
  43. void *context)
  44. {
  45. if (!i4_threads_supported())
  46. i4_error("threads not supported");
  47. que_lock.lock();
  48. read_request r(fd, buffer, size, call, context);
  49. if (!request_que.que(r))
  50. {
  51. que_lock.unlock();
  52. return i4_F;
  53. }
  54. que_lock.unlock();
  55. sig.signal();
  56. return i4_T;
  57. }
  58. void i4_async_reader::emulate_speeds(read_request &r)
  59. {
  60. if (emulation)
  61. {
  62. i4_time_class now, start;
  63. while (start.milli_diff(now) < r.size*1000/(1000*1024) + 20*1000)
  64. {
  65. i4_thread_yield();
  66. now.get();
  67. }
  68. }
  69. }
  70. void i4_async_reader::PRIVATE_thread()
  71. {
  72. read_request r;
  73. sw32 amount;
  74. do
  75. {
  76. while (request_que.empty()) // if no more request to satisfy, wait for main process signal
  77. {
  78. stop=i4_F;
  79. sig.wait_signal();
  80. }
  81. if (!stop)
  82. {
  83. que_lock.lock();
  84. if (request_que.deque(r))
  85. {
  86. que_lock.unlock();
  87. emulate_speeds(r);
  88. amount = read(r.fd, r.buffer, r.size);
  89. r.callback(amount, r.context);
  90. }
  91. else que_lock.unlock();
  92. }
  93. } while (!stop);
  94. stop=i4_F;
  95. }