@@ -62,54 +62,21 @@ class Channel
6262 }
6363
6464 template <typename U, typename Duration>
65- bool BlockTryPush (U && t, Duration const & timeout) const
65+ bool TimedPush (U && t, Duration const & timeout) const
6666 {
67- int interval = 1 ;
68- auto begin = std::chrono::high_resolution_clock::now ();
69- while (!TryPush (std::forward<U>(t))) {
70- auto now = std::chrono::high_resolution_clock::now ();
71- if (std::chrono::duration_cast<Duration>(now - begin) >= timeout)
72- return false ;
73-
74- interval = std::min (32 , interval << 1 );
75- g_Scheduler.SleepSwitch (interval);
76- }
77-
78- return true ;
67+ return impl_->TimedPush (std::forward<U>(t), timeout);
7968 }
8069
8170 template <typename U, typename Duration>
82- bool BlockTryPop (U & t, Duration const & timeout) const
71+ bool TimedPop (U & t, Duration const & timeout) const
8372 {
84- int interval = 1 ;
85- auto begin = std::chrono::high_resolution_clock::now ();
86- while (!TryPop (t)) {
87- auto now = std::chrono::high_resolution_clock::now ();
88- if (std::chrono::duration_cast<Duration>(now - begin) >= timeout)
89- return false ;
90-
91- interval = std::min (32 , interval << 1 );
92- g_Scheduler.SleepSwitch (interval);
93- }
94-
95- return true ;
73+ return impl_->TimedPop (t, timeout);
9674 }
9775
9876 template <typename Duration>
99- bool BlockTryPop (nullptr_t ignore, Duration const & timeout) const
77+ bool TimedPop (nullptr_t ignore, Duration const & timeout) const
10078 {
101- int interval = 1 ;
102- auto begin = std::chrono::high_resolution_clock::now ();
103- while (!TryPop (ignore)) {
104- auto now = std::chrono::high_resolution_clock::now ();
105- if (std::chrono::duration_cast<Duration>(now - begin) >= timeout)
106- return false ;
107-
108- interval = std::min (32 , interval << 1 );
109- g_Scheduler.SleepSwitch (interval);
110- }
111-
112- return true ;
79+ return impl_->TimedPop (ignore, timeout);
11380 }
11481
11582 bool Unique () const
@@ -170,6 +137,72 @@ class Channel
170137 }
171138 }
172139
140+ // write
141+ template <typename U, typename Duration>
142+ bool TimedPush (U && t, Duration const & dur)
143+ {
144+ if (!write_block_.CoBlockWaitTimed (std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
145+ return false ;
146+
147+ {
148+ std::unique_lock<CoMutex> lock (queue_lock_);
149+ queue_.push (std::forward<U>(t));
150+ }
151+
152+ read_block_.Wakeup ();
153+ return true ;
154+ }
155+
156+ // read
157+ template <typename U, typename Duration>
158+ bool TimedPop (U & t, Duration const & dur)
159+ {
160+ write_block_.Wakeup ();
161+ if (!read_block_.CoBlockWaitTimed (std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
162+ {
163+ if (write_block_.TryBlockWait ())
164+ return false ;
165+ else
166+ {
167+ while (!read_block_.TryBlockWait ())
168+ if (write_block_.TryBlockWait ())
169+ return false ;
170+ else
171+ g_Scheduler.CoYield ();
172+ }
173+ }
174+
175+ std::unique_lock<CoMutex> lock (queue_lock_);
176+ t = std::move (queue_.front ());
177+ queue_.pop ();
178+ return true ;
179+ }
180+
181+ // read and ignore
182+ template <typename Duration>
183+ bool TimedPop (nullptr_t ignore, Duration const & dur)
184+ {
185+ write_block_.Wakeup ();
186+ if (!read_block_.CoBlockWaitTimed (std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
187+ {
188+ if (write_block_.TryBlockWait ())
189+ return false ;
190+ else
191+ {
192+ while (!read_block_.TryBlockWait ())
193+ if (write_block_.TryBlockWait ())
194+ return false ;
195+ else
196+ g_Scheduler.CoYield ();
197+ }
198+ }
199+
200+ std::unique_lock<CoMutex> lock (queue_lock_);
201+ queue_.pop ();
202+ return true ;
203+ }
204+
205+
173206 // try write
174207 template <typename U>
175208 bool TryPush (U && t)
@@ -266,37 +299,15 @@ class Channel<void>
266299 }
267300
268301 template <typename Duration>
269- bool BlockTryPush (nullptr_t ignore, Duration const & timeout) const
302+ bool TimedPush (nullptr_t ignore, Duration const & timeout) const
270303 {
271- int interval = 1 ;
272- auto begin = std::chrono::high_resolution_clock::now ();
273- while (!TryPush (ignore)) {
274- auto now = std::chrono::high_resolution_clock::now ();
275- if (std::chrono::duration_cast<Duration>(now - begin) >= timeout)
276- return false ;
277-
278- interval = std::min (32 , interval << 1 );
279- g_Scheduler.SleepSwitch (interval);
280- }
281-
282- return true ;
304+ return impl_->TimedPush (ignore, timeout);
283305 }
284306
285307 template <typename Duration>
286- bool BlockTryPop (nullptr_t ignore, Duration const & timeout) const
308+ bool TimedPop (nullptr_t ignore, Duration const & timeout) const
287309 {
288- int interval = 1 ;
289- auto begin = std::chrono::high_resolution_clock::now ();
290- while (!TryPop (ignore)) {
291- auto now = std::chrono::high_resolution_clock::now ();
292- if (std::chrono::duration_cast<Duration>(now - begin) >= timeout)
293- return false ;
294-
295- interval = std::min (32 , interval << 1 );
296- g_Scheduler.SleepSwitch (interval);
297- }
298-
299- return true ;
310+ return impl_->TimedPop (ignore, timeout);
300311 }
301312
302313 bool Unique () const
@@ -329,6 +340,39 @@ class Channel<void>
329340 read_block_.CoBlockWait ();
330341 }
331342
343+ // write
344+ template <typename Duration>
345+ bool TimedPush (nullptr_t ignore, Duration const & dur)
346+ {
347+ if (!write_block_.CoBlockWaitTimed (std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
348+ return false ;
349+
350+ read_block_.Wakeup ();
351+ return true ;
352+ }
353+
354+ // read
355+ template <typename Duration>
356+ bool TimedPop (nullptr_t ignore, Duration const & dur)
357+ {
358+ write_block_.Wakeup ();
359+ if (!read_block_.CoBlockWaitTimed (std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
360+ {
361+ if (write_block_.TryBlockWait ())
362+ return false ;
363+ else
364+ {
365+ while (!read_block_.TryBlockWait ())
366+ if (write_block_.TryBlockWait ())
367+ return false ;
368+ else
369+ g_Scheduler.CoYield ();
370+ }
371+ }
372+
373+ return true ;
374+ }
375+
332376 // try write
333377 bool TryPush (nullptr_t ignore)
334378 {
@@ -352,8 +396,6 @@ class Channel<void>
352396 return true ;
353397 }
354398 };
355-
356-
357399};
358400
359401} // namespace co
0 commit comments