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 |
|
---|
9 | #include "file/async.hh"
|
---|
10 | #include "threads/threads.hh"
|
---|
11 | #include "time/time.hh"
|
---|
12 | #include "error/error.hh"
|
---|
13 |
|
---|
14 | i4_async_reader::i4_async_reader(char *name) : sig(name)
|
---|
15 | {
|
---|
16 | emulation=i4_F;
|
---|
17 | stop=i4_F;
|
---|
18 | }
|
---|
19 |
|
---|
20 | void i4_async_reader_thread_start(void *arg)
|
---|
21 | {
|
---|
22 | ((i4_async_reader *)arg)->PRIVATE_thread();
|
---|
23 | }
|
---|
24 |
|
---|
25 | void i4_async_reader::init()
|
---|
26 | {
|
---|
27 | if (i4_threads_supported())
|
---|
28 | {
|
---|
29 | stop=i4_T;
|
---|
30 | i4_add_thread(i4_async_reader_thread_start, STACK_SIZE, this);
|
---|
31 | }
|
---|
32 | }
|
---|
33 |
|
---|
34 | void i4_async_reader::uninit()
|
---|
35 | {
|
---|
36 | if (i4_threads_supported())
|
---|
37 | {
|
---|
38 | while (stop==i4_T) // wait to thread is read to be stopped
|
---|
39 | i4_thread_yield();
|
---|
40 |
|
---|
41 | stop=i4_T;
|
---|
42 | sig.signal();
|
---|
43 | while (stop)
|
---|
44 | i4_thread_yield();
|
---|
45 | }
|
---|
46 | }
|
---|
47 |
|
---|
48 | i4_bool i4_async_reader::start_read(int fd, void *buffer, w32 size,
|
---|
49 | i4_file_class::async_callback call,
|
---|
50 | void *context)
|
---|
51 | {
|
---|
52 | if (!i4_threads_supported())
|
---|
53 | i4_error("threads not supported");
|
---|
54 |
|
---|
55 | que_lock.lock();
|
---|
56 |
|
---|
57 | read_request r(fd, buffer, size, call, context);
|
---|
58 | if (!request_que.que(r))
|
---|
59 | {
|
---|
60 | que_lock.unlock();
|
---|
61 | return i4_F;
|
---|
62 | }
|
---|
63 | que_lock.unlock();
|
---|
64 |
|
---|
65 | sig.signal();
|
---|
66 | return i4_T;
|
---|
67 | }
|
---|
68 |
|
---|
69 |
|
---|
70 | void i4_async_reader::emulate_speeds(read_request &r)
|
---|
71 | {
|
---|
72 | if (emulation)
|
---|
73 | {
|
---|
74 | i4_time_class now, start;
|
---|
75 | while (start.milli_diff(now) < r.size*1000/(1000*1024) + 20*1000)
|
---|
76 | {
|
---|
77 | i4_thread_yield();
|
---|
78 | now.get();
|
---|
79 | }
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 |
|
---|
84 | void i4_async_reader::PRIVATE_thread()
|
---|
85 | {
|
---|
86 | read_request r;
|
---|
87 | sw32 amount;
|
---|
88 |
|
---|
89 | do
|
---|
90 | {
|
---|
91 | while (request_que.empty()) // if no more request to satisfy, wait for main process signal
|
---|
92 | {
|
---|
93 | stop=i4_F;
|
---|
94 | sig.wait_signal();
|
---|
95 | }
|
---|
96 |
|
---|
97 | if (!stop)
|
---|
98 | {
|
---|
99 | que_lock.lock();
|
---|
100 |
|
---|
101 | if (request_que.deque(r))
|
---|
102 | {
|
---|
103 | que_lock.unlock();
|
---|
104 | emulate_speeds(r);
|
---|
105 |
|
---|
106 | amount = read(r.fd, r.buffer, r.size);
|
---|
107 |
|
---|
108 | r.callback(amount, r.context);
|
---|
109 | }
|
---|
110 | else que_lock.unlock();
|
---|
111 | }
|
---|
112 |
|
---|
113 | } while (!stop);
|
---|
114 | stop=i4_F;
|
---|
115 | }
|
---|