Skip to content

Commit 11921b4

Browse files
add UI interruption
1 parent 7722ca7 commit 11921b4

9 files changed

Lines changed: 90 additions & 85 deletions

File tree

Binary file not shown.

dispatch/dispatch.cpp

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ namespace dispatch
2121
{
2222
#pragma mark - TaskPriority
2323

24-
struct TaskPriority{
24+
struct TaskPriority
25+
{
2526
TaskPriority(QUEUE_PRIORITY priority, Functor task) : priority(priority), task(task), timestamp(std::clock()){}
2627

2728
QUEUE_PRIORITY priority;
2829
Functor task;
2930
std::clock_t timestamp;
3031
};
32+
3133
#pragma mark - Queue
3234

3335
typedef std::function<void (Functor)> AppendTask;
3436

35-
struct QueueImpl {
37+
struct QueueImpl
38+
{
3639
QUEUE_PRIORITY priority;
3740
AppendTask append_task;
3841

@@ -47,7 +50,8 @@ namespace dispatch
4750

4851
#pragma mark - ThreadPool
4952

50-
class ThreadPool {
53+
class ThreadPool
54+
{
5155
public:
5256
ThreadPool(size_t);
5357
static ThreadPool* instance();
@@ -64,6 +68,7 @@ namespace dispatch
6468
std::mutex main_mutex;
6569
std::condition_variable main_condition;
6670

71+
Functor main_loop_need_update;
6772
private:
6873
friend class QueueImpl;
6974

@@ -73,7 +78,8 @@ namespace dispatch
7378

7479
#pragma mark - Task comparator
7580

76-
bool operator<(const QueueImpl::Task& firsTask, const QueueImpl::Task& secondTask) {
81+
bool operator<(const QueueImpl::Task& firsTask, const QueueImpl::Task& secondTask)
82+
{
7783
if ( firsTask->priority == secondTask->priority )
7884
return firsTask->timestamp > secondTask->timestamp;
7985
else
@@ -82,10 +88,13 @@ namespace dispatch
8288

8389
#pragma mark - ThreadPool
8490

85-
void ThreadPool::add_worker(){
86-
workers.push_back(std::thread([&]{
91+
void ThreadPool::add_worker()
92+
{
93+
workers.push_back(std::thread([&]
94+
{
8795
QueueImpl::Task task;
88-
while(true){
96+
while(true)
97+
{
8998
{
9099
std::unique_lock<std::mutex> lock(this->queue_mutex);
91100

@@ -103,24 +112,27 @@ namespace dispatch
103112
}));
104113
}
105114

106-
ThreadPool::ThreadPool(size_t threads) : stop(false){
115+
ThreadPool::ThreadPool(size_t threads) : stop(false)
116+
{
107117
for (int i = 0; i < threads; ++i)
108118
add_worker();
109119
}
110120

111-
ThreadPool::~ThreadPool(){
121+
ThreadPool::~ThreadPool()
122+
{
112123
stop = true;
113124
condition.notify_all();
114-
115-
// the destructor joins all threads
125+
116126
for(size_t i = 0;i<workers.size();++i)
117127
workers[i].join();
118128
}
119129

120-
ThreadPool* ThreadPool::instance(){
130+
ThreadPool* ThreadPool::instance()
131+
{
121132
static std::once_flag flag;
122133
static ThreadPool* instance = nullptr;
123-
std::call_once(flag, [](){
134+
std::call_once(flag, []()
135+
{
124136
int default_not_computable_value = 5;
125137
int number_of_threads = std::thread::hardware_concurrency();
126138
instance = new ThreadPool(number_of_threads?: default_not_computable_value);
@@ -130,47 +142,63 @@ namespace dispatch
130142

131143
#pragma mark -
132144

133-
Queue get_main_queue(){
134-
return std::make_shared<QueueImpl>([](Functor task) {
145+
Queue get_main_queue()
146+
{
147+
return std::make_shared<QueueImpl>([](Functor task)
148+
{
135149
std::unique_lock<std::mutex> lock(ThreadPool::instance()->main_mutex);
136150
ThreadPool::instance()->main_queue.push(std::make_shared<TaskPriority>(QUEUE_PRIORITY::HIGH, task));
151+
if (ThreadPool::instance()->main_loop_need_update != nullptr)
152+
ThreadPool::instance()->main_loop_need_update();
137153
});
138154
}
139155

140-
void process_main_loop(){
156+
Queue get_queue_with_priority(QUEUE_PRIORITY priority)
157+
{
158+
return std::make_shared<QueueImpl>(priority, [=](Functor task)
159+
{
160+
{
161+
std::unique_lock<std::mutex> lock(ThreadPool::instance()->queue_mutex);
162+
ThreadPool::instance()->tasks.push(std::make_shared<TaskPriority>(priority, task));
163+
}
164+
ThreadPool::instance()->condition.notify_one();
165+
});
166+
}
167+
168+
void process_main_loop()
169+
{
141170
ThreadPool* pool = ThreadPool::instance();
142171
std::unique_lock<std::mutex> lock(pool->main_mutex);
143-
while (!pool->main_queue.empty()){
172+
while (!pool->main_queue.empty())
173+
{
144174
QueueImpl::Task task = pool->main_queue.front();
145175
pool->main_queue.pop();
146176
task->task();
147177
}
148178
}
149179

150-
void main_loop(Functor function){
180+
void main_loop(Functor function)
181+
{
151182
Queue main_queue = get_main_queue();
152-
while (!ThreadPool::instance()->stop){
183+
while (!ThreadPool::instance()->stop)
184+
{
153185
async(main_queue, function);
154186
process_main_loop();
155187
}
156188
}
157189

158-
void async(Queue queue, Functor function){
190+
void async(Queue queue, Functor function)
191+
{
159192
queue->append_task(function);
160193
}
161194

162-
void exit(){
195+
void exit()
196+
{
163197
ThreadPool::instance()->stop = true;
164198
}
165199

166-
Queue get_queue_with_priority(QUEUE_PRIORITY priority){
167-
return std::make_shared<QueueImpl>(priority, [=](Functor task) {
168-
{
169-
std::unique_lock<std::mutex> lock(ThreadPool::instance()->queue_mutex);
170-
ThreadPool::instance()->tasks.push(std::make_shared<TaskPriority>(priority, task));
171-
}
172-
173-
ThreadPool::instance()->condition.notify_one();
174-
});
200+
void set_main_loop_process_callback(Functor update_callback)
201+
{
202+
ThreadPool::instance()->main_loop_need_update = update_callback;
175203
}
176204
}

dispatch/dispatch.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,19 @@ namespace dispatch
2323
} QUEUE_PRIORITY;
2424

2525
typedef std::function<void ()> Functor;
26-
26+
2727
class QueueImpl;
2828
typedef std::shared_ptr<QueueImpl> Queue;
2929

3030
Queue get_main_queue();
3131
Queue get_queue_with_priority(QUEUE_PRIORITY priority);
3232

33-
void process_main_loop();
34-
void main_loop(Functor function);
3533
void async(Queue queue, Functor function);
34+
3635
void exit();
36+
void main_loop(Functor function);
37+
void process_main_loop();
38+
void set_main_loop_process_callback(Functor functor);
3739
}
3840

3941
#endif

dispatch/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main(int argc, const char * argv[])
4242
dispatch::main_loop([]{
4343
std::cout << ".";
4444
});
45-
45+
4646
return 0;
4747
}
4848

Binary file not shown.

ios/ios/AppDelegate.mm

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,50 +19,16 @@ @implementation AppDelegate
1919

2020
@synthesize runLoopObserver;
2121

22-
static void onRunLoop(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void* info)
22+
-(void)dispatchMainThread
2323
{
2424
dispatch::process_main_loop();
2525
}
2626

27-
- (void)attachObservers
28-
{
29-
if (runLoopObserver != NULL)
30-
return;
31-
32-
CFRunLoopObserverContext context =
33-
{
34-
0, // Version of this structure. Must be zero.
35-
(__bridge void*)self, // Info pointer: a reference to this UpdateTimer.
36-
NULL, // Retain callback for info pointer.
37-
NULL, // Release callback for info pointer.
38-
NULL // Copy description.
39-
};
40-
41-
runLoopObserver = CFRunLoopObserverCreate(NULL,
42-
kCFRunLoopBeforeWaiting | kCFRunLoopExit, // Observe when the run loop is waiting and just before it exits.
43-
true, // Repeats.
44-
0, // Priority index. Use zero because there's currently no reason to do otherwise.
45-
onRunLoop,
46-
&context); // Copied by CFRunLoopObserverCreate, no need to pass a heap pointer.
47-
48-
CFRunLoopAddObserver(CFRunLoopGetCurrent(), runLoopObserver, kCFRunLoopCommonModes);
49-
}
50-
51-
- (void)detachObservers
52-
{
53-
if (runLoopObserver == NULL)
54-
return;
55-
56-
CFRunLoopObserverInvalidate(runLoopObserver);
57-
CFRelease(runLoopObserver);
58-
runLoopObserver = NULL;
59-
}
60-
6127
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
6228
{
63-
[self attachObservers];
64-
65-
// Override point for customization after application launch.
29+
dispatch::set_main_loop_process_callback([=]{
30+
[self performSelectorOnMainThread:@selector(dispatchMainThread) withObject:nil waitUntilDone:NO];
31+
});
6632
return YES;
6733
}
6834

@@ -91,7 +57,6 @@ - (void)applicationDidBecomeActive:(UIApplication *)application
9157

9258
- (void)applicationWillTerminate:(UIApplication *)application
9359
{
94-
[self detachObservers];
9560

9661
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
9762
}

ios/ios/ViewController.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
@interface ViewController : UIViewController
1212

13-
- (IBAction)onRunButtonClick:(id)sender;
13+
-(IBAction)onRunButtonClick:(id)sender;
14+
15+
@property (strong, nonatomic) IBOutlet UITableView *tableView;
1416

1517
@end

ios/ios/ViewController.mm

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,32 @@
77
//
88

99
#import "ViewController.h"
10+
1011
#import "dispatch.h"
12+
1113
#import <string>
1214
#import <iostream>
1315

14-
@interface ViewController ()
15-
16-
@end
17-
1816
@implementation ViewController
1917

2018
- (IBAction)onRunButtonClick:(id)sender
2119
{
22-
dispatch::Queue queue = dispatch::get_queue_with_priority(dispatch::QUEUE_PRIORITY::HIGH);
23-
24-
dispatch::Queue main_queue = dispatch::get_main_queue();
2520
for (int i = 0; i < 20; ++i)
2621
{
27-
dispatch::async(queue, [=](){
22+
dispatch::async(dispatch::get_queue_with_priority(dispatch::QUEUE_PRIORITY::HIGH), [=](){
2823

2924
std::string first_string = std::to_string(i);
3025

31-
dispatch::async(main_queue, [=]{
32-
26+
dispatch::async(dispatch::get_main_queue(), [=]{
27+
3328
std::string second_string = std::to_string(i+1);
3429

3530
std::cout << first_string << " -> " << second_string << std::endl;
31+
32+
[self.tableView reloadData];
3633
});
3734
});
3835
}
39-
4036
}
37+
4138
@end

ios/ios/en.lproj/MainStoryboard.storyboard

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@
2525
<action selector="onRunButtonClick:" destination="2" eventType="touchUpInside" id="cS2-Dv-cjl"/>
2626
</connections>
2727
</button>
28+
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="Wx2-He-U1k">
29+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
30+
</tableView>
2831
</subviews>
2932
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
3033
<constraints>
34+
<constraint firstItem="Wx2-He-U1k" firstAttribute="top" secondItem="TKA-PP-F8H" secondAttribute="bottom" constant="8" symbolic="YES" type="default" id="6YF-Gd-xpU"/>
35+
<constraint firstAttribute="bottom" secondItem="Wx2-He-U1k" secondAttribute="bottom" constant="20" symbolic="YES" type="default" id="DQH-53-iv0"/>
3136
<constraint firstAttribute="trailing" secondItem="TKA-PP-F8H" secondAttribute="trailing" constant="20" symbolic="YES" type="default" id="IQh-zZ-mLE"/>
3237
<constraint firstItem="TKA-PP-F8H" firstAttribute="top" secondItem="3" secondAttribute="top" constant="20" symbolic="YES" type="default" id="IfE-4Y-rwZ"/>
3338
<constraint firstItem="TKA-PP-F8H" firstAttribute="leading" secondItem="3" secondAttribute="leading" constant="20" symbolic="YES" type="default" id="Qeg-9b-CS5"/>
39+
<constraint firstAttribute="trailing" secondItem="Wx2-He-U1k" secondAttribute="trailing" constant="20" symbolic="YES" type="default" id="Zp0-Kg-1nn"/>
40+
<constraint firstItem="Wx2-He-U1k" firstAttribute="leading" secondItem="3" secondAttribute="leading" constant="20" symbolic="YES" type="default" id="gT3-od-ZKD"/>
3441
</constraints>
3542
</view>
43+
<connections>
44+
<outlet property="tableView" destination="Wx2-He-U1k" id="FrQ-7q-UIQ"/>
45+
</connections>
3646
</viewController>
3747
<placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
3848
</objects>
@@ -46,6 +56,7 @@
4656
<source key="sourceIdentifier" type="project" relativePath="./Classes/ViewController.h"/>
4757
<relationships>
4858
<relationship kind="action" name="onRunButtonClick:"/>
59+
<relationship kind="outlet" name="tableView" candidateClass="UITableView"/>
4960
</relationships>
5061
</class>
5162
</classes>

0 commit comments

Comments
 (0)