diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 1 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 65 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.h | 42 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 12 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 2 | ||||
-rw-r--r-- | chrome/browser/dom_ui/new_tab_ui_uitest.cc | 12 | ||||
-rw-r--r-- | chrome/browser/sessions/session_restore_uitest.cc | 24 | ||||
-rw-r--r-- | chrome/browser/ui/tests/browser_uitest.cc | 17 | ||||
-rw-r--r-- | chrome/common/automation_messages_internal.h | 9 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.cc | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.h | 3 | ||||
-rw-r--r-- | chrome/test/automation/tab_proxy.cc | 5 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.cc | 8 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.h | 2 | ||||
-rw-r--r-- | chrome/worker/worker_uitest.cc | 4 |
15 files changed, 175 insertions, 35 deletions
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index a8d531a..d558c45 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -29,6 +29,7 @@ #include "chrome/common/notification_observer.h" #include "ipc/ipc_message.h" #include "ipc/ipc_channel.h" + #if defined(OS_WIN) #include "gfx/native_widget_types.h" #include "views/event.h" diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index 111c220..3d1f780 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -204,6 +204,7 @@ bool NavigationControllerRestoredObserver::FinishedRestoring() { void NavigationControllerRestoredObserver::SendDone() { DCHECK(reply_message_ != NULL); + AutomationMsg_WaitForTabToBeRestored::WriteReplyParams(reply_message_, true); automation_->Send(reply_message_); } @@ -750,7 +751,6 @@ struct CommandNotification { const struct CommandNotification command_notifications[] = { {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED}, - {IDC_NEW_TAB, NotificationType::INITIAL_NEW_TAB_UI_LOAD}, // Returns as soon as the restored tab is created. To further wait until // the content page is loaded, use WaitForTabToBeRestored. @@ -776,6 +776,10 @@ bool ExecuteBrowserCommandObserver::CreateAndRegisterObserver( IPC::Message* reply_message) { bool result = true; switch (command) { + case IDC_NEW_TAB: { + new NewTabObserver(automation, reply_message); + break; + } case IDC_NEW_WINDOW: case IDC_NEW_INCOGNITO_WINDOW: { BrowserOpenedNotificationObserver* observer = @@ -1639,3 +1643,62 @@ void RendererProcessClosedObserver::Observe( AutomationJSONReply(automation_, reply_message_).SendSuccess(NULL); delete this; } + +NewTabObserver::NewTabObserver(AutomationProvider* automation, + IPC::Message* reply_message) + : automation_(automation), + reply_message_(reply_message) { + // Use TAB_PARENTED to detect the new tab. + registrar_.Add(this, + NotificationType::TAB_PARENTED, + NotificationService::AllSources()); +} + +void NewTabObserver::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK_EQ(NotificationType::TAB_PARENTED, type.value); + // We found the new tab. Now wait for it to load. + NavigationController* controller = Source<NavigationController>(source).ptr(); + AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_, true); + automation_->AddNavigationStatusListener( + controller, reply_message_, 1, false); + delete this; +} + +NewTabObserver::~NewTabObserver() { +} + +WaitForProcessLauncherThreadToGoIdleObserver:: +WaitForProcessLauncherThreadToGoIdleObserver( + AutomationProvider* automation, IPC::Message* reply_message) + : automation_(automation), + reply_message_(reply_message) { + // Balanced in RunOnUIThread. + AddRef(); + BrowserThread::PostTask( + BrowserThread::PROCESS_LAUNCHER, FROM_HERE, + NewRunnableMethod( + this, + &WaitForProcessLauncherThreadToGoIdleObserver:: + RunOnProcessLauncherThread)); +} + +WaitForProcessLauncherThreadToGoIdleObserver:: +~WaitForProcessLauncherThreadToGoIdleObserver() { +} + +void WaitForProcessLauncherThreadToGoIdleObserver:: +RunOnProcessLauncherThread() { + BrowserThread::PostTask( + BrowserThread::PROCESS_LAUNCHER, FROM_HERE, + NewRunnableMethod( + this, + &WaitForProcessLauncherThreadToGoIdleObserver::RunOnUIThread)); +} + +void WaitForProcessLauncherThreadToGoIdleObserver::RunOnUIThread() { + automation_->Send(reply_message_); + Release(); +} + diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h index 6cbe1bd..d7a0c5e 100644 --- a/chrome/browser/automation/automation_provider_observers.h +++ b/chrome/browser/automation/automation_provider_observers.h @@ -1028,5 +1028,47 @@ class RendererProcessClosedObserver : public NotificationObserver { DISALLOW_COPY_AND_ASSIGN(RendererProcessClosedObserver); }; +// Observer used to listen for new tab creation to complete. +class NewTabObserver : public NotificationObserver { + public: + NewTabObserver(AutomationProvider* automation, IPC::Message* reply_message); + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) OVERRIDE; + + private: + ~NewTabObserver(); + + NotificationRegistrar registrar_; + scoped_refptr<AutomationProvider> automation_; + IPC::Message* reply_message_; + + DISALLOW_COPY_AND_ASSIGN(NewTabObserver); +}; + +// Posts a task to the PROCESS_LAUNCHER thread, once processed posts a task +// back to the UI thread that notifies the provider we're done. +class WaitForProcessLauncherThreadToGoIdleObserver + : public base::RefCountedThreadSafe< + WaitForProcessLauncherThreadToGoIdleObserver> { + public: + WaitForProcessLauncherThreadToGoIdleObserver( + AutomationProvider* automation, IPC::Message* reply_message); + + private: + friend class base::RefCountedThreadSafe< + WaitForProcessLauncherThreadToGoIdleObserver>; + + ~WaitForProcessLauncherThreadToGoIdleObserver(); + + void RunOnProcessLauncherThread(); + void RunOnUIThread(); + + scoped_refptr<AutomationProvider> automation_; + IPC::Message* reply_message_; + + DISALLOW_COPY_AND_ASSIGN(WaitForProcessLauncherThreadToGoIdleObserver); +}; #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_ diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 088a23a..d4c946b 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -393,6 +393,9 @@ bool TestingAutomationProvider::OnMessageReceived( IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting) IPC_MESSAGE_HANDLER(AutomationMsg_LoadBlockedPlugins, LoadBlockedPlugins) IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme) + IPC_MESSAGE_HANDLER_DELAY_REPLY( + AutomationMsg_WaitForProcessLauncherThreadToGoIdle, + WaitForProcessLauncherThreadToGoIdle) IPC_MESSAGE_UNHANDLED( handled = AutomationProvider::OnMessageReceived(message)) @@ -1262,6 +1265,10 @@ void TestingAutomationProvider::WaitForTabToBeRestored( NavigationController* tab = tab_tracker_->GetResource(tab_handle); restore_tracker_.reset( new NavigationControllerRestoredObserver(this, tab, reply_message)); + } else { + AutomationMsg_WaitForTabToBeRestored::WriteReplyParams( + reply_message, false); + Send(reply_message); } } @@ -4469,6 +4476,11 @@ void TestingAutomationProvider::ResetToDefaultTheme() { profile_->ClearTheme(); } +void TestingAutomationProvider::WaitForProcessLauncherThreadToGoIdle( + IPC::Message* reply_message) { + new WaitForProcessLauncherThreadToGoIdleObserver(this, reply_message); +} + // TODO(brettw) change this to accept GURLs when history supports it void TestingAutomationProvider::OnRedirectQueryComplete( HistoryService::Handle request_handle, diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index 9c8d471c..27252ef 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -775,6 +775,8 @@ class TestingAutomationProvider : public AutomationProvider, // Resets to the default theme. void ResetToDefaultTheme(); + void WaitForProcessLauncherThreadToGoIdle(IPC::Message* reply_message); + // Callback for history redirect queries. virtual void OnRedirectQueryComplete( HistoryService::Handle request_handle, diff --git a/chrome/browser/dom_ui/new_tab_ui_uitest.cc b/chrome/browser/dom_ui/new_tab_ui_uitest.cc index f912db0..1da7349 100644 --- a/chrome/browser/dom_ui/new_tab_ui_uitest.cc +++ b/chrome/browser/dom_ui/new_tab_ui_uitest.cc @@ -40,8 +40,6 @@ TEST_F(NewTabUITest, NTPHasThumbnails) { // Bring up a new tab page. ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); - int load_time; - ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time)); scoped_refptr<TabProxy> tab = window->GetActiveTab(); ASSERT_TRUE(tab.get()); @@ -63,8 +61,6 @@ TEST_F(NewTabUITest, DISABLED_NTPHasLoginName) { "user@gmail.com")); // Bring up a new tab page. ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); - int load_time; - ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time)); scoped_refptr<TabProxy> tab = window->GetActiveTab(); ASSERT_TRUE(tab.get()); @@ -94,8 +90,6 @@ TEST_F(NewTabUITest, AboutHangInNTP) { // Bring up a new tab page. ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); - int load_time; - ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time)); scoped_refptr<TabProxy> tab = window->GetActiveTab(); ASSERT_TRUE(tab.get()); @@ -104,7 +98,7 @@ TEST_F(NewTabUITest, AboutHangInNTP) { // Visit about:hang again in another NTP. Don't bother waiting for the // NTP to load, because it's hung. - ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); + ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB)); scoped_refptr<TabProxy> tab2 = window->GetActiveTab(); ASSERT_TRUE(tab2.get()); ASSERT_TRUE(tab2->NavigateToURLAsync(GURL(chrome::kAboutHangURL))); @@ -131,8 +125,6 @@ TEST_F(NewTabUIProcessPerTabTest, NavBeforeNTPCommits) { // Bring up a new tab page. ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); - int load_time; - ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time)); scoped_refptr<TabProxy> tab = window->GetActiveTab(); ASSERT_TRUE(tab.get()); @@ -140,7 +132,7 @@ TEST_F(NewTabUIProcessPerTabTest, NavBeforeNTPCommits) { ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kAboutHangURL))); // Visit a normal URL in another NTP that hasn't committed. - ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); + ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB)); scoped_refptr<TabProxy> tab2 = window->GetActiveTab(); ASSERT_TRUE(tab2.get()); ASSERT_TRUE(tab2->NavigateToURL(GURL("data:text/html,hello world"))); diff --git a/chrome/browser/sessions/session_restore_uitest.cc b/chrome/browser/sessions/session_restore_uitest.cc index 54d2510..1985e9d 100644 --- a/chrome/browser/sessions/session_restore_uitest.cc +++ b/chrome/browser/sessions/session_restore_uitest.cc @@ -450,8 +450,7 @@ TEST_F(SessionRestoreUITest, TwoWindowsCloseOneRestoreOnlyOne) { // process-per-site and process-per-site-instance, because we treat the new tab // as a special case in process-per-site-instance so that it only ever uses one // process.) -// Flaky as per http://crbug.com/52022 -TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) { +TEST_F(SessionRestoreUITest, ShareProcessesOnRestore) { if (ProxyLauncher::in_process_renderer()) { // No point in running this test in single process mode. return; @@ -469,7 +468,8 @@ TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) { ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count)); ASSERT_EQ(tab_count + 2, new_tab_count); - int expected_process_count = GetBrowserProcessCount(); + int expected_process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&expected_process_count)); int expected_tab_count = new_tab_count; // Restart. @@ -483,16 +483,16 @@ TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) { ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); ASSERT_EQ(expected_tab_count, tab_count); - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(tab_count - 2)); - ASSERT_TRUE(tab_proxy.get() != NULL); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - tab_proxy = browser_proxy->GetTab(tab_count - 1); - ASSERT_TRUE(tab_proxy.get() != NULL); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); + for (int i = 0; i < expected_tab_count; ++i) { + scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(i)); + ASSERT_TRUE(tab_proxy.get() != NULL); + ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( + TestTimeouts::action_max_timeout_ms())); + } - ASSERT_EQ(expected_process_count, GetBrowserProcessCount()); + int process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&process_count)); + ASSERT_EQ(expected_process_count, process_count); } } // namespace diff --git a/chrome/browser/ui/tests/browser_uitest.cc b/chrome/browser/ui/tests/browser_uitest.cc index 3320dd4..7d77744 100644 --- a/chrome/browser/ui/tests/browser_uitest.cc +++ b/chrome/browser/ui/tests/browser_uitest.cc @@ -102,7 +102,8 @@ TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { tab->NavigateToURL(net::FilePathToFileURL(test_file)); int orig_tab_count = -1; ASSERT_TRUE(window->GetTabCount(&orig_tab_count)); - int orig_process_count = GetBrowserProcessCount(); + int orig_process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&orig_process_count)); ASSERT_GE(orig_process_count, 1); // Use JavaScript URL to "fork" a new tab, just like Gmail. (Open tab to a @@ -115,7 +116,9 @@ TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { // process for it. ASSERT_TRUE(tab->NavigateToURLAsync(fork_url)); PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); - ASSERT_EQ(orig_process_count + 1, GetBrowserProcessCount()); + int process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&process_count)); + ASSERT_EQ(orig_process_count + 1, process_count); int new_tab_count = -1; ASSERT_TRUE(window->GetTabCount(&new_tab_count)); ASSERT_EQ(orig_tab_count + 1, new_tab_count); @@ -154,7 +157,8 @@ TEST_F(BrowserTest, MAYBE_OtherRedirectsDontForkProcess) { tab->NavigateToURL(net::FilePathToFileURL(test_file))); int orig_tab_count = -1; ASSERT_TRUE(window->GetTabCount(&orig_tab_count)); - int orig_process_count = GetBrowserProcessCount(); + int orig_process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&orig_process_count)); ASSERT_GE(orig_process_count, 1); // Use JavaScript URL to almost fork a new tab, but not quite. (Leave the @@ -168,7 +172,9 @@ TEST_F(BrowserTest, MAYBE_OtherRedirectsDontForkProcess) { // Make sure that a new tab but not new process has been created. ASSERT_TRUE(tab->NavigateToURLAsync(dont_fork_url)); base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); - ASSERT_EQ(orig_process_count, GetBrowserProcessCount()); + int process_count = 0; + ASSERT_TRUE(GetBrowserProcessCount(&process_count)); + ASSERT_EQ(orig_process_count, process_count); int new_tab_count = -1; ASSERT_TRUE(window->GetTabCount(&new_tab_count)); ASSERT_EQ(orig_tab_count + 1, new_tab_count); @@ -183,7 +189,8 @@ TEST_F(BrowserTest, MAYBE_OtherRedirectsDontForkProcess) { // Make sure that no new process has been created. ASSERT_TRUE(tab->NavigateToURLAsync(dont_fork_url2)); base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); - ASSERT_EQ(orig_process_count, GetBrowserProcessCount()); + ASSERT_TRUE(GetBrowserProcessCount(&process_count)); + ASSERT_EQ(orig_process_count, process_count); } TEST_F(VisibleBrowserTest, WindowOpenClose) { diff --git a/chrome/common/automation_messages_internal.h b/chrome/common/automation_messages_internal.h index 87359f5..790afda 100644 --- a/chrome/common/automation_messages_internal.h +++ b/chrome/common/automation_messages_internal.h @@ -533,8 +533,8 @@ IPC_MESSAGE_ROUTED3(AutomationMsg_OpenURL, // - int: handle of the tab // Response: // - bool: whether the operation was successful. -IPC_SYNC_MESSAGE_CONTROL1_0(AutomationMsg_WaitForTabToBeRestored, - int) +IPC_SYNC_MESSAGE_CONTROL1_1(AutomationMsg_WaitForTabToBeRestored, + int, bool) // This message is an outgoing message from Chrome to an external host. // It is a notification that a navigation happened @@ -1445,3 +1445,8 @@ IPC_MESSAGE_ROUTED3(AutomationMsg_JavaScriptStressTestControl, int /* tab handle */, int /* command */, int /* type or run */) + +// This message posts a task to the PROCESS_LAUNCHER thread. Once processed +// the response is sent back. This is useful when you want to make sure all +// changes to the number of processes have completed. +IPC_SYNC_MESSAGE_CONTROL0_0(AutomationMsg_WaitForProcessLauncherThreadToGoIdle) diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index 989c91a..461b3e4 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -203,6 +203,10 @@ void AutomationProxy::SignalAppLaunch(const std::string& version_string) { app_launched_.Signal(); } +bool AutomationProxy::WaitForProcessLauncherThreadToGoIdle() { + return Send(new AutomationMsg_WaitForProcessLauncherThreadToGoIdle()); +} + bool AutomationProxy::WaitForInitialLoads() { return initial_loads_complete_.TimedWait(command_execution_timeout_); } diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h index 323538c..cfc8c8b 100644 --- a/chrome/test/automation/automation_proxy.h +++ b/chrome/test/automation/automation_proxy.h @@ -87,6 +87,9 @@ class AutomationProxy : public IPC::Channel::Listener, // set_perform_version_check() to set it. AutomationLaunchResult WaitForAppLaunch(); + // See description in AutomationMsg_WaitForProcessLauncherThreadToGoIdle. + bool WaitForProcessLauncherThreadToGoIdle() WARN_UNUSED_RESULT; + // Waits for any initial page loads to complete. // NOTE: this only fires once for a run of the application. // Returns true if the load is successful diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc index f7908c4..5625c40 100644 --- a/chrome/test/automation/tab_proxy.cc +++ b/chrome/test/automation/tab_proxy.cc @@ -563,7 +563,10 @@ void TabProxy::HandleMessageFromExternalHost(const std::string& message, bool TabProxy::WaitForTabToBeRestored(uint32 timeout_ms) { if (!is_valid()) return false; - return sender_->Send(new AutomationMsg_WaitForTabToBeRestored(handle_)); + bool succeeded = false; + return sender_->Send( + new AutomationMsg_WaitForTabToBeRestored(handle_, &succeeded)) && + succeeded; } bool TabProxy::GetSecurityState(SecurityStyle* security_style, diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc index af957ab..1ebb523 100644 --- a/chrome/test/ui/ui_test.cc +++ b/chrome/test/ui/ui_test.cc @@ -595,8 +595,12 @@ void UITest::StopHttpServer() { #endif } -int UITest::GetBrowserProcessCount() { - return GetRunningChromeProcesses(browser_process_id()).size(); +bool UITest::GetBrowserProcessCount(int* count) { + *count = 0; + if (!automation()->WaitForProcessLauncherThreadToGoIdle()) + return false; + *count = GetRunningChromeProcesses(browser_process_id()).size(); + return true; } static DictionaryValue* LoadDictionaryValueFromPath(const FilePath& path) { diff --git a/chrome/test/ui/ui_test.h b/chrome/test/ui/ui_test.h index c813292..234dc85 100644 --- a/chrome/test/ui/ui_test.h +++ b/chrome/test/ui/ui_test.h @@ -391,7 +391,7 @@ class UITest : public UITestBase, public PlatformTest { // Count the number of active browser processes launched by this test. // The count includes browser sub-processes. - int GetBrowserProcessCount(); + bool GetBrowserProcessCount(int* count) WARN_UNUSED_RESULT; // Returns a copy of local state preferences. The caller is responsible for // deleting the returned object. Returns NULL if there is an error. diff --git a/chrome/worker/worker_uitest.cc b/chrome/worker/worker_uitest.cc index 6c01b66..c76333c 100644 --- a/chrome/worker/worker_uitest.cc +++ b/chrome/worker/worker_uitest.cc @@ -92,7 +92,9 @@ class WorkerTest : public UILayoutTest { int cur_process_count; for (int i = 0; i < 10; ++i) { - cur_process_count = GetBrowserProcessCount(); + cur_process_count = 0; + if (!GetBrowserProcessCount(&cur_process_count)) + return false; if (cur_process_count == number_of_processes) return true; |