{"action":"created","comment":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments/140392359","pull_request_review_id":64460536,"id":140392359,"diff_hunk":"@@ -65,39 +65,46 @@ - (void) endBackgrounding {\n \n // Called when the replicator goes idle (from -updateActive)\n - (void) okToEndBackgrounding {\n-    dispatch_async(dispatch_get_main_queue(), ^{\n-        if ([_bgMonitor hasBackgroundTask]) {\n-            _deepBackground = YES;\n-            [self updateSuspended];\n-            LogTo(Sync, @\"%@: Now idle; ending background task\", self);\n-            [_bgMonitor endBackgroundTask];  // will probably suspend the process immediately\n-        }\n-    });\n+    if ([_bgMonitor hasBackgroundTask]) {\n+        _deepBackground = YES;\n+        [self updateSuspended];\n+        LogTo(Sync, @\"%@: Now idle; ending background task\", self);\n+        [_bgMonitor endBackgroundTask];  // will probably suspend the process immediately\n+    }\n+}\n+\n+- (void) updateSuspended {\n+    BOOL suspended = (_filesystemUnavailable || _deepBackground);\n+    self.suspended = suspended;\n }\n \n \n ////// All the methods below are called on the MAIN THREAD, not the replicator thread ////////\n \n \n - (void) appBackgrounding {\n-    if (_active && [_bgMonitor beginBackgroundTaskNamed: self.description]) {\n-        LogTo(Sync, @\"%@: App backgrounding; starting temporary background task\", self);\n-    } else {\n-        LogTo(Sync, @\"%@: App backgrounding, but replication is inactive; suspending\", self);\n-        _deepBackground = YES;\n-        [self updateSuspended];\n-    }\n+    [self.db doSync: ^{\n+        if (_active && [_bgMonitor beginBackgroundTaskNamed: self.description]) {","path":"Source/CBLRestReplicator+Backgrounding.m","position":38,"original_position":38,"commit_id":"6cee45b22a58be34e9b128a8254c0fd46b4c9634","original_commit_id":"6cee45b22a58be34e9b128a8254c0fd46b4c9634","user":{"login":"snej","id":43241,"avatar_url":"https://avatars2.githubusercontent.com/u/43241?v=4","gravatar_id":"","url":"https://api.github.com/users/snej","html_url":"https://github.com/snej","followers_url":"https://api.github.com/users/snej/followers","following_url":"https://api.github.com/users/snej/following{/other_user}","gists_url":"https://api.github.com/users/snej/gists{/gist_id}","starred_url":"https://api.github.com/users/snej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snej/subscriptions","organizations_url":"https://api.github.com/users/snej/orgs","repos_url":"https://api.github.com/users/snej/repos","events_url":"https://api.github.com/users/snej/events{/privacy}","received_events_url":"https://api.github.com/users/snej/received_events","type":"User","site_admin":false},"body":"The doc-comment of -beginBackgroundTaskNamed says \"Should be called on the main thread\" (probably because it calls into `UIApplication`) but this is calling it from the db thread.\r\n\r\nLooking at the git log of this file I see that commit 50cc50a from last November says \"...Thread-safety improvements in CBLRestReplicator+Backgrounding: make sure UIApplication is only called on the main thread.\"\r\n\r\nIf you need to access `_active` on the db thread, can you do just that one check in the -doSync: block? Or more simply, make `_active` an atomic bool?","created_at":"2017-09-22T00:51:27Z","updated_at":"2017-09-22T01:01:04Z","html_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1905#discussion_r140392359","pull_request_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments/140392359"},"html":{"href":"https://github.com/couchbase/couchbase-lite-ios/pull/1905#discussion_r140392359"},"pull_request":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905"}}},"pull_request":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905","id":142208370,"html_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1905","diff_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1905.diff","patch_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1905.patch","issue_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1905","number":1905,"state":"open","locked":false,"title":"Fixed #1898 threading issue in replicator backgrounding","user":{"login":"pasin","id":801454,"avatar_url":"https://avatars1.githubusercontent.com/u/801454?v=4","gravatar_id":"","url":"https://api.github.com/users/pasin","html_url":"https://github.com/pasin","followers_url":"https://api.github.com/users/pasin/followers","following_url":"https://api.github.com/users/pasin/following{/other_user}","gists_url":"https://api.github.com/users/pasin/gists{/gist_id}","starred_url":"https://api.github.com/users/pasin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pasin/subscriptions","organizations_url":"https://api.github.com/users/pasin/orgs","repos_url":"https://api.github.com/users/pasin/repos","events_url":"https://api.github.com/users/pasin/events{/privacy}","received_events_url":"https://api.github.com/users/pasin/received_events","type":"User","site_admin":false},"body":"* Currently some variables (_active, _filesystemUnavailable, and _deepBackground) could be accessed from different threads (main thread and replicator thread). Fixing this by always executes background/forground handling codes on the replicator thread.\r\n\r\n* This is also fixed the issue that the replicator (especially pull replicator) is suspended immediately when starting it in the background. Basically there is a race when accessing the _active variable (#1898)","created_at":"2017-09-20T21:32:44Z","updated_at":"2017-09-22T01:01:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"406e1df7ee403dcc0d635f60f9cd2470300a03e2","assignee":{"login":"snej","id":43241,"avatar_url":"https://avatars2.githubusercontent.com/u/43241?v=4","gravatar_id":"","url":"https://api.github.com/users/snej","html_url":"https://github.com/snej","followers_url":"https://api.github.com/users/snej/followers","following_url":"https://api.github.com/users/snej/following{/other_user}","gists_url":"https://api.github.com/users/snej/gists{/gist_id}","starred_url":"https://api.github.com/users/snej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snej/subscriptions","organizations_url":"https://api.github.com/users/snej/orgs","repos_url":"https://api.github.com/users/snej/repos","events_url":"https://api.github.com/users/snej/events{/privacy}","received_events_url":"https://api.github.com/users/snej/received_events","type":"User","site_admin":false},"assignees":[{"login":"snej","id":43241,"avatar_url":"https://avatars2.githubusercontent.com/u/43241?v=4","gravatar_id":"","url":"https://api.github.com/users/snej","html_url":"https://github.com/snej","followers_url":"https://api.github.com/users/snej/followers","following_url":"https://api.github.com/users/snej/following{/other_user}","gists_url":"https://api.github.com/users/snej/gists{/gist_id}","starred_url":"https://api.github.com/users/snej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snej/subscriptions","organizations_url":"https://api.github.com/users/snej/orgs","repos_url":"https://api.github.com/users/snej/repos","events_url":"https://api.github.com/users/snej/events{/privacy}","received_events_url":"https://api.github.com/users/snej/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905/commits","review_comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905/comments","review_comment_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments{/number}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1905/comments","statuses_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/6cee45b22a58be34e9b128a8254c0fd46b4c9634","head":{"label":"couchbase:feature/fix_repl_bg","ref":"feature/fix_repl_bg","sha":"6cee45b22a58be34e9b128a8254c0fd46b4c9634","user":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"repo":{"id":7948548,"name":"couchbase-lite-ios","full_name":"couchbase/couchbase-lite-ios","owner":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/couchbase/couchbase-lite-ios","description":"Lightweight, embedded, syncable NoSQL database engine for iOS (and Mac!) apps.","fork":false,"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios","forks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/forks","keys_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/teams","hooks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/hooks","issue_events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/events{/number}","events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/events","assignees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/assignees{/user}","branches_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/branches{/branch}","tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/tags","blobs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/{sha}","languages_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/languages","stargazers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/stargazers","contributors_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contributors","subscribers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscribers","subscription_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscription","commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contents/{+path}","compare_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/merges","archive_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/downloads","issues_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues{/number}","pulls_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls{/number}","milestones_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/milestones{/number}","notifications_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/labels{/name}","releases_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/releases{/id}","deployments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/deployments","created_at":"2013-02-01T00:09:26Z","updated_at":"2017-09-21T14:27:45Z","pushed_at":"2017-09-21T21:36:05Z","git_url":"git://github.com/couchbase/couchbase-lite-ios.git","ssh_url":"git@github.com:couchbase/couchbase-lite-ios.git","clone_url":"https://github.com/couchbase/couchbase-lite-ios.git","svn_url":"https://github.com/couchbase/couchbase-lite-ios","homepage":"","size":59946,"stargazers_count":1242,"watchers_count":1242,"language":"Objective-C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":246,"mirror_url":null,"open_issues_count":169,"forks":246,"open_issues":169,"watchers":1242,"default_branch":"master"}},"base":{"label":"couchbase:master","ref":"master","sha":"b47fadc17a263f3399a06fe307ac7019f8e7499d","user":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"repo":{"id":7948548,"name":"couchbase-lite-ios","full_name":"couchbase/couchbase-lite-ios","owner":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/couchbase/couchbase-lite-ios","description":"Lightweight, embedded, syncable NoSQL database engine for iOS (and Mac!) apps.","fork":false,"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios","forks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/forks","keys_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/teams","hooks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/hooks","issue_events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/events{/number}","events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/events","assignees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/assignees{/user}","branches_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/branches{/branch}","tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/tags","blobs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/{sha}","languages_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/languages","stargazers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/stargazers","contributors_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contributors","subscribers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscribers","subscription_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscription","commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contents/{+path}","compare_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/merges","archive_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/downloads","issues_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues{/number}","pulls_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls{/number}","milestones_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/milestones{/number}","notifications_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/labels{/name}","releases_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/releases{/id}","deployments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/deployments","created_at":"2013-02-01T00:09:26Z","updated_at":"2017-09-21T14:27:45Z","pushed_at":"2017-09-21T21:36:05Z","git_url":"git://github.com/couchbase/couchbase-lite-ios.git","ssh_url":"git@github.com:couchbase/couchbase-lite-ios.git","clone_url":"https://github.com/couchbase/couchbase-lite-ios.git","svn_url":"https://github.com/couchbase/couchbase-lite-ios","homepage":"","size":59946,"stargazers_count":1242,"watchers_count":1242,"language":"Objective-C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":246,"mirror_url":null,"open_issues_count":169,"forks":246,"open_issues":169,"watchers":1242,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905"},"html":{"href":"https://github.com/couchbase/couchbase-lite-ios/pull/1905"},"issue":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1905"},"comments":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1905/comments"},"review_comments":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905/comments"},"review_comment":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1905/commits"},"statuses":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/6cee45b22a58be34e9b128a8254c0fd46b4c9634"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"snej"}}