<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <oleacc.h>

#include "app/l10n_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/test/in_process_browser_test.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    IAccessible* acc_obj = NULL;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       FLAKY_TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);

  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  IAccessible* acc_obj = NULL;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  // TODO(ctguil): Fix. The window title could be "New Tab - Chromium" or
  // "about:blank - Chromium"
  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_PRODUCT_NAME),
                        ROLE_SYSTEM_WINDOW);

  acc_obj->Release();
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  IAccessible* acc_obj = NULL;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);

  acc_obj->Release();
}
}  // Namespace.

<commit_msg>Fix flakyness of browser_tests:BrowserViewsAccessibilityTest.TestChromeWindowAccObj<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <oleacc.h>

#include "app/l10n_util.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    ScopedComPtr<IAccessible> acc_obj;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);
  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
  std::wstring title =
      l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT,
                            ASCIIToWide(chrome::kAboutBlankURL));
  TestAccessibilityInfo(acc_obj, title, ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);
}
}  // Namespace.

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: customcontrolcontainer.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 17:55:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_fpicker.hxx"

#ifndef _CUSTOMCONTROLCONTAINER_HXX_
#include "customcontrolcontainer.hxx"
#endif

#include <algorithm>
#include <functional>

//-----------------------------------
//
//-----------------------------------

namespace /* private */
{
    void DeleteCustomControl(CCustomControl* aCustomControl)
    {
        delete aCustomControl;
    };

    void AlignCustomControl(CCustomControl* aCustomControl)
    {
        aCustomControl->Align();
    };

    class CSetFontHelper
    {
    public:
        CSetFontHelper(HFONT hFont) :
            m_hFont(hFont)
        {
        }

        void SAL_CALL operator()(CCustomControl* aCustomControl)
        {
            aCustomControl->SetFont(m_hFont);
        }

    private:
        HFONT m_hFont;
    };
}

//-----------------------------------
//
//-----------------------------------

CCustomControlContainer::~CCustomControlContainer()
{
    RemoveAllControls();
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::Align()
{
    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        AlignCustomControl);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::SetFont(HFONT hFont)
{
    CSetFontHelper aSetFontHelper(hFont);

    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        aSetFontHelper);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::AddControl(CCustomControl* aCustomControl)
{
    m_ControlContainer.push_back(aCustomControl);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::RemoveControl(CCustomControl* aCustomControl)
{
    ControlContainer_t::iterator iter_end = m_ControlContainer.end();

    ControlContainer_t::iterator iter =
        std::find(m_ControlContainer.begin(),iter_end,aCustomControl);

    if (iter != iter_end)
    {
        delete *iter;
        m_ControlContainer.remove(aCustomControl);
    }
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::RemoveAllControls()
{
    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        DeleteCustomControl);

    m_ControlContainer.clear();
}
<commit_msg>INTEGRATION: CWS changefileheader (1.3.158); FILE MERGED 2008/04/01 12:30:51 thb 1.3.158.2: #i85898# Stripping all external header guards 2008/03/31 13:13:18 rt 1.3.158.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: customcontrolcontainer.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_fpicker.hxx"
#include "customcontrolcontainer.hxx"

#include <algorithm>
#include <functional>

//-----------------------------------
//
//-----------------------------------

namespace /* private */
{
    void DeleteCustomControl(CCustomControl* aCustomControl)
    {
        delete aCustomControl;
    };

    void AlignCustomControl(CCustomControl* aCustomControl)
    {
        aCustomControl->Align();
    };

    class CSetFontHelper
    {
    public:
        CSetFontHelper(HFONT hFont) :
            m_hFont(hFont)
        {
        }

        void SAL_CALL operator()(CCustomControl* aCustomControl)
        {
            aCustomControl->SetFont(m_hFont);
        }

    private:
        HFONT m_hFont;
    };
}

//-----------------------------------
//
//-----------------------------------

CCustomControlContainer::~CCustomControlContainer()
{
    RemoveAllControls();
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::Align()
{
    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        AlignCustomControl);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::SetFont(HFONT hFont)
{
    CSetFontHelper aSetFontHelper(hFont);

    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        aSetFontHelper);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::AddControl(CCustomControl* aCustomControl)
{
    m_ControlContainer.push_back(aCustomControl);
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::RemoveControl(CCustomControl* aCustomControl)
{
    ControlContainer_t::iterator iter_end = m_ControlContainer.end();

    ControlContainer_t::iterator iter =
        std::find(m_ControlContainer.begin(),iter_end,aCustomControl);

    if (iter != iter_end)
    {
        delete *iter;
        m_ControlContainer.remove(aCustomControl);
    }
}

//-----------------------------------
//
//-----------------------------------

void SAL_CALL CCustomControlContainer::RemoveAllControls()
{
    std::for_each(
        m_ControlContainer.begin(),
        m_ControlContainer.end(),
        DeleteCustomControl);

    m_ControlContainer.clear();
}
<|endoftext|>


<commit_before><commit_msg>Rolled back new changes in integer_xl class.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <seastar/testing/thread_test_case.hh>

#include "cdc/cdc.hh"
#include "tests/cql_assertions.hh"
#include "tests/cql_test_env.hh"

SEASTAR_THREAD_TEST_CASE(test_with_cdc_parameter) {
    do_with_cql_env_thread([](cql_test_env& e) {
        struct expected {
            bool enabled = false;
            bool preimage = false;
            bool postimage = false;
            int ttl = 86400;
        };

        auto assert_cdc = [&] (const expected& exp) {
            BOOST_REQUIRE_EQUAL(exp.enabled,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().enabled());
            if (exp.enabled) {
                e.require_table_exists("ks", cdc::log_name("tbl")).get();
                e.require_table_exists("ks", cdc::desc_name("tbl")).get();
                auto msg = e.execute_cql(format("select node_ip, shard_id from ks.{};", cdc::desc_name("tbl"))).get0();
                std::vector<std::vector<bytes_opt>> expected_rows;
                expected_rows.reserve(smp::count);
                auto ip = inet_addr_type->decompose(
                        utils::fb_utilities::get_broadcast_address().addr());
                for (int i = 0; i < static_cast<int>(smp::count); ++i) {
                    expected_rows.push_back({ip, int32_type->decompose(i)});
                }
                assert_that(msg).is_rows().with_rows_ignore_order(std::move(expected_rows));
            } else {
                e.require_table_does_not_exist("ks", cdc::log_name("tbl")).get();
                e.require_table_does_not_exist("ks", cdc::desc_name("tbl")).get();
            }
            BOOST_REQUIRE_EQUAL(exp.preimage,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().preimage());
            BOOST_REQUIRE_EQUAL(exp.postimage,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().postimage());
            BOOST_REQUIRE_EQUAL(exp.ttl,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().ttl());
        };

        auto test = [&] (const sstring& create_prop,
                         const sstring& alter1_prop,
                         const sstring& alter2_prop,
                         const expected& create_expected,
                         const expected& alter1_expected,
                         const expected& alter2_expected) {
            e.execute_cql(format("CREATE TABLE ks.tbl (a int PRIMARY KEY) {}", create_prop)).get();
            assert_cdc(create_expected);
            e.execute_cql(format("ALTER TABLE ks.tbl WITH cdc = {}", alter1_prop)).get();
            assert_cdc(alter1_expected);
            e.execute_cql(format("ALTER TABLE ks.tbl WITH cdc = {}", alter2_prop)).get();
            assert_cdc(alter2_expected);
            e.execute_cql("DROP TABLE ks.tbl").get();
            e.require_table_does_not_exist("ks", cdc::log_name("tbl")).get();
            e.require_table_does_not_exist("ks", cdc::desc_name("tbl")).get();
        };

        test("", "{'enabled':'true'}", "{'enabled':'false'}", {false}, {true}, {false});
        test("WITH cdc = {'enabled':'true'}", "{'enabled':'false'}", "{'enabled':'true'}", {true}, {false}, {true});
        test("WITH cdc = {'enabled':'false'}", "{'enabled':'true'}", "{'enabled':'false'}", {false}, {true}, {false});
        test("", "{'enabled':'true','preimage':'true','postimage':'true','ttl':'1'}", "{'enabled':'false'}", {false}, {true, true, true, 1}, {false});
        test("WITH cdc = {'enabled':'true','preimage':'true','postimage':'true','ttl':'1'}", "{'enabled':'false'}", "{'enabled':'true','preimage':'false','postimage':'true','ttl':'2'}", {true, true, true, 1}, {false}, {true, false, true, 2});
    }).get();
}

<commit_msg>test: add test_partition_key_logging<commit_after>/*
 * Copyright (C) 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <seastar/testing/thread_test_case.hh>

#include "cdc/cdc.hh"
#include "tests/cql_assertions.hh"
#include "tests/cql_test_env.hh"
#include "transport/messages/result_message.hh"

SEASTAR_THREAD_TEST_CASE(test_with_cdc_parameter) {
    do_with_cql_env_thread([](cql_test_env& e) {
        struct expected {
            bool enabled = false;
            bool preimage = false;
            bool postimage = false;
            int ttl = 86400;
        };

        auto assert_cdc = [&] (const expected& exp) {
            BOOST_REQUIRE_EQUAL(exp.enabled,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().enabled());
            if (exp.enabled) {
                e.require_table_exists("ks", cdc::log_name("tbl")).get();
                e.require_table_exists("ks", cdc::desc_name("tbl")).get();
                auto msg = e.execute_cql(format("select node_ip, shard_id from ks.{};", cdc::desc_name("tbl"))).get0();
                std::vector<std::vector<bytes_opt>> expected_rows;
                expected_rows.reserve(smp::count);
                auto ip = inet_addr_type->decompose(
                        utils::fb_utilities::get_broadcast_address().addr());
                for (int i = 0; i < static_cast<int>(smp::count); ++i) {
                    expected_rows.push_back({ip, int32_type->decompose(i)});
                }
                assert_that(msg).is_rows().with_rows_ignore_order(std::move(expected_rows));
            } else {
                e.require_table_does_not_exist("ks", cdc::log_name("tbl")).get();
                e.require_table_does_not_exist("ks", cdc::desc_name("tbl")).get();
            }
            BOOST_REQUIRE_EQUAL(exp.preimage,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().preimage());
            BOOST_REQUIRE_EQUAL(exp.postimage,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().postimage());
            BOOST_REQUIRE_EQUAL(exp.ttl,
                    e.local_db().find_schema("ks", "tbl")->cdc_options().ttl());
        };

        auto test = [&] (const sstring& create_prop,
                         const sstring& alter1_prop,
                         const sstring& alter2_prop,
                         const expected& create_expected,
                         const expected& alter1_expected,
                         const expected& alter2_expected) {
            e.execute_cql(format("CREATE TABLE ks.tbl (a int PRIMARY KEY) {}", create_prop)).get();
            assert_cdc(create_expected);
            e.execute_cql(format("ALTER TABLE ks.tbl WITH cdc = {}", alter1_prop)).get();
            assert_cdc(alter1_expected);
            e.execute_cql(format("ALTER TABLE ks.tbl WITH cdc = {}", alter2_prop)).get();
            assert_cdc(alter2_expected);
            e.execute_cql("DROP TABLE ks.tbl").get();
            e.require_table_does_not_exist("ks", cdc::log_name("tbl")).get();
            e.require_table_does_not_exist("ks", cdc::desc_name("tbl")).get();
        };

        test("", "{'enabled':'true'}", "{'enabled':'false'}", {false}, {true}, {false});
        test("WITH cdc = {'enabled':'true'}", "{'enabled':'false'}", "{'enabled':'true'}", {true}, {false}, {true});
        test("WITH cdc = {'enabled':'false'}", "{'enabled':'true'}", "{'enabled':'false'}", {false}, {true}, {false});
        test("", "{'enabled':'true','preimage':'true','postimage':'true','ttl':'1'}", "{'enabled':'false'}", {false}, {true, true, true, 1}, {false});
        test("WITH cdc = {'enabled':'true','preimage':'true','postimage':'true','ttl':'1'}", "{'enabled':'false'}", "{'enabled':'true','preimage':'false','postimage':'true','ttl':'2'}", {true, true, true, 1}, {false}, {true, false, true, 2});
    }).get();
}

SEASTAR_THREAD_TEST_CASE(test_partition_key_logging) {
    do_with_cql_env_thread([](cql_test_env& e) {
        cquery_nofail(e, "CREATE TABLE ks.tbl (pk int, pk2 int, ck int, ck2 int, val int, PRIMARY KEY((pk, pk2), ck, ck2)) WITH cdc = {'enabled':'true'}");
        cquery_nofail(e, "INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 11, 111, 1111, 11111)");
        cquery_nofail(e, "INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 22, 222, 2222, 22222)");
        cquery_nofail(e, "INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 33, 333, 3333, 33333)");
        cquery_nofail(e, "INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 44, 444, 4444, 44444)");
        cquery_nofail(e, "INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(2, 11, 111, 1111, 11111)");
        cquery_nofail(e, "DELETE val FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck = 111 AND ck2 = 1111");
        cquery_nofail(e, "DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck = 111 AND ck2 = 1111");
        cquery_nofail(e, "DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck > 222 AND ck <= 444");
        cquery_nofail(e, "UPDATE ks.tbl SET val = 555 WHERE pk = 2 AND pk2 = 11 AND ck = 111 AND ck2 = 1111");
        cquery_nofail(e, "DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11");
        auto msg = e.execute_cql(format("SELECT time, \"_pk\", \"_pk2\" FROM ks.{}", cdc::log_name("tbl"))).get0();
        auto rows = dynamic_pointer_cast<cql_transport::messages::result_message::rows>(msg);
        BOOST_REQUIRE(rows);
        auto rs = rows->rs().result_set().rows();
        std::vector<std::vector<bytes_opt>> results;
        for (auto it = rs.begin(); it != rs.end(); ++it) {
            results.push_back(*it);
        }
        std::sort(results.begin(), results.end(),
                [] (const std::vector<bytes_opt>& a, const std::vector<bytes_opt>& b) {
                    return timeuuid_type->as_less_comparator()(*a[0], *b[0]);
                });
        auto actual_i = results.begin();
        auto actual_end = results.end();
        auto assert_row = [&] (int pk, int pk2) {
            BOOST_REQUIRE(actual_i != actual_end);
            auto& actual_row = *actual_i;
            BOOST_REQUIRE_EQUAL(int32_type->decompose(pk), actual_row[1]);
            BOOST_REQUIRE_EQUAL(int32_type->decompose(pk2), actual_row[2]);
            ++actual_i;
        };
        // INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 11, 111, 1111, 11111)
        assert_row(1, 11);
        // INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 22, 222, 2222, 22222)
        assert_row(1, 22);
        // INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 33, 333, 3333, 33333)
        assert_row(1, 33);
        // INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(1, 44, 444, 4444, 44444)
        assert_row(1, 44);
        // INSERT INTO ks.tbl(pk, pk2, ck, ck2, val) VALUES(2, 11, 111, 1111, 11111)
        assert_row(2, 11);
        // DELETE val FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck = 111 AND ck2 = 1111
        assert_row(1, 11);
        // DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck = 111 AND ck2 = 1111
        assert_row(1, 11);
        // DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11 AND ck > 222 AND ck <= 444
        assert_row(1, 11);
        // UPDATE ks.tbl SET val = 555 WHERE pk = 2 AND pk2 = 11 AND ck = 111 AND ck2 = 1111
        assert_row(2, 11);
        // DELETE FROM ks.tbl WHERE pk = 1 AND pk2 = 11
        assert_row(1, 11);
        BOOST_REQUIRE(actual_i == actual_end);
    }).get();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unordered_map>

#include "io_interface.h"

#include "matrix_config.h"
#include "mem_worker_thread.h"
#include "EM_object.h"
#include "local_mem_buffer.h"

namespace fm
{

namespace detail
{

#ifdef USE_HWLOC
std::vector<int> get_cpus(int node_id)
{
	std::vector<int> io_cpus = safs::get_io_cpus();
	std::vector<int> logical_units = cpus.get_node(node_id).get_logical_units();
	std::set<int> cpu_set(logical_units.begin(), logical_units.end());
	// Remove the logical units where I/O threads run.
	for (size_t j = 0; j < io_cpus.size(); j++)
		cpu_set.erase(io_cpus[j]);
	return std::vector<int>(cpu_set.begin(), cpu_set.end());
}
#endif

mem_thread_pool::mem_thread_pool(int num_nodes, int nthreads_per_node)
{
	tot_num_tasks = 0;
	threads.resize(num_nodes);
	for (int i = 0; i < num_nodes; i++) {
		// Get the CPU cores that are in node i.
#ifdef USE_HWLOC
		std::vector<int> cpus = get_cpus(i);
#endif
		threads[i].resize(nthreads_per_node);
		for (int j = 0; j < nthreads_per_node; j++) {
			std::string name
				= std::string("mem-worker-") + itoa(i) + "-" + itoa(j);
#ifdef USE_HWLOC
			if (safs::get_io_cpus().empty())
				threads[i][j] = std::shared_ptr<pool_task_thread>(
						new pool_task_thread(i * nthreads_per_node + j, name, i));
			else
				threads[i][j] = std::shared_ptr<pool_task_thread>(
						new pool_task_thread(i * nthreads_per_node + j, name,
							cpus, i));
#else
			threads[i][j] = std::shared_ptr<pool_task_thread>(
					new pool_task_thread(i * nthreads_per_node + j, name, i));
#endif
			threads[i][j]->start();
		}
	}
	ntasks_per_node.resize(num_nodes);
}

/*
 * This method dispatches tasks in a round-robin fashion.
 */
void mem_thread_pool::process_task(int node_id, thread_task *task)
{
	if (node_id < 0)
		node_id = tot_num_tasks % get_num_nodes();

	assert((size_t) node_id < threads.size());
	size_t idx = ntasks_per_node[node_id] % threads[node_id].size();
	threads[node_id][idx]->add_task(task);
	ntasks_per_node[node_id]++;
	tot_num_tasks++;
}

void mem_thread_pool::wait4complete()
{
	for (size_t i = 0; i < threads.size(); i++) {
		size_t nthreads = threads[i].size();
		for (size_t j = 0; j < nthreads; j++)
			threads[i][j]->wait4complete();
	}

	// After all workers complete, we should try to clear the memory buffers
	// in each worker thread to reduce memory consumption.
	// We might want to keep the memory buffer for I/O on dense matrices.
	if (matrix_conf.is_keep_mem_buf())
		detail::local_mem_buffer::clear_bufs(
				detail::local_mem_buffer::MAT_PORTION);
	else
		detail::local_mem_buffer::clear_bufs();
}

size_t mem_thread_pool::get_num_pending() const
{
	size_t ret = 0;
	for (size_t i = 0; i < threads.size(); i++) {
		size_t nthreads = threads[i].size();
		for (size_t j = 0; j < nthreads; j++)
			ret += threads[i][j]->get_num_pending();
	}
	return ret;
}

static mem_thread_pool::ptr global_threads;
enum thread_pool_state {
	UNINIT,
	ACTIVE,
	INACTIVE,
};
static thread_pool_state pool_state = thread_pool_state::UNINIT;

/*
 * When we disable thread pool, we use the main thread to perform
 * computation.
 */
bool mem_thread_pool::disable_thread_pool()
{
	pool_state = thread_pool_state::INACTIVE;
	return true;
}

bool mem_thread_pool::enable_thread_pool()
{
	pool_state = thread_pool_state::ACTIVE;
	return true;
}

mem_thread_pool::ptr mem_thread_pool::get_global_mem_threads()
{
	assert(pool_state != thread_pool_state::INACTIVE);
	if (global_threads == NULL) {
		int nthreads_per_node
			= matrix_conf.get_num_DM_threads() / matrix_conf.get_num_nodes();
		assert(nthreads_per_node > 0);
		global_threads = mem_thread_pool::create(matrix_conf.get_num_nodes(),
				nthreads_per_node);
		enable_thread_pool();
	}
	return global_threads;
}

size_t mem_thread_pool::get_global_num_threads()
{
	// When we disable the thread pool, we use the main thread for computation.
	// So the number of threads is 1.
	if (pool_state == thread_pool_state::INACTIVE)
		return 1;
	else
		return get_global_mem_threads()->get_num_threads();
}

int mem_thread_pool::get_curr_thread_id()
{
	// When we disable the thread pool, we use the main thread for computation.
	// And we use 0 as the thread id of the main thread.
	if (pool_state == thread_pool_state::INACTIVE)
		return 0;
	else {
		detail::pool_task_thread *curr
			= dynamic_cast<detail::pool_task_thread *>(thread::get_curr_thread());
		if (curr)
			return curr->get_pool_thread_id();
		else
			return -1;
	}
}

void mem_thread_pool::init_global_mem_threads(int num_nodes,
		int nthreads_per_node)
{
	if (global_threads == NULL) {
		global_threads = mem_thread_pool::create(num_nodes, nthreads_per_node);
		enable_thread_pool();
	}
}

void mem_thread_pool::destroy()
{
	global_threads = NULL;
}

void io_worker_task::run()
{
	std::vector<safs::io_interface::ptr> ios;
	pthread_spin_lock(&lock);
	for (auto it = EM_objs.begin(); it != EM_objs.end(); it++) {
		std::vector<safs::io_interface::ptr> tmp = (*it)->create_ios();
		ios.insert(ios.end(), tmp.begin(), tmp.end());
	}
	pthread_spin_unlock(&lock);
	safs::io_select::ptr select = safs::create_io_select(ios);

	// The task runs until there are no tasks left in the queue.
	while (dispatch->issue_task())
		safs::wait4ios(select, max_pending_ios);
	// Test if all I/O instances have processed all requests.
	size_t num_pending = safs::wait4ios(select, 0);
	assert(num_pending == 0);

	pthread_spin_lock(&lock);
	EM_objs.clear();
	pthread_spin_unlock(&lock);

	for (size_t i = 0; i < ios.size(); i++) {
		portion_callback &cb = static_cast<portion_callback &>(
				ios[i]->get_callback());
		assert(!cb.has_callback());
	}
}

global_counter::global_counter()
{
	counts.resize(mem_thread_pool::get_global_num_threads() + 1);
	reset();
}

void global_counter::inc(size_t val)
{
	int id = mem_thread_pool::get_curr_thread_id();
	// the main thread has id of -1.
	counts[id + 1].count += val;
}

void global_counter::reset()
{
	for (size_t i = 0; i < counts.size(); i++)
		counts[i].count = 0;
}

size_t global_counter::get() const
{
	size_t tot = 0;
	for (size_t i = 0; i < counts.size(); i++)
		tot += counts[i].count;
	return tot;
}

}

}
<commit_msg>[Matrix]: thread pool counts the main thread.<commit_after>/*
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unordered_map>

#include "io_interface.h"

#include "matrix_config.h"
#include "mem_worker_thread.h"
#include "EM_object.h"
#include "local_mem_buffer.h"

namespace fm
{

namespace detail
{

#ifdef USE_HWLOC
std::vector<int> get_cpus(int node_id)
{
	std::vector<int> io_cpus = safs::get_io_cpus();
	std::vector<int> logical_units = cpus.get_node(node_id).get_logical_units();
	std::set<int> cpu_set(logical_units.begin(), logical_units.end());
	// Remove the logical units where I/O threads run.
	for (size_t j = 0; j < io_cpus.size(); j++)
		cpu_set.erase(io_cpus[j]);
	return std::vector<int>(cpu_set.begin(), cpu_set.end());
}
#endif

mem_thread_pool::mem_thread_pool(int num_nodes, int nthreads_per_node)
{
	tot_num_tasks = 0;
	threads.resize(num_nodes);
	for (int i = 0; i < num_nodes; i++) {
		// Get the CPU cores that are in node i.
#ifdef USE_HWLOC
		std::vector<int> cpus = get_cpus(i);
#endif
		threads[i].resize(nthreads_per_node);
		for (int j = 0; j < nthreads_per_node; j++) {
			std::string name
				= std::string("mem-worker-") + itoa(i) + "-" + itoa(j);
#ifdef USE_HWLOC
			if (safs::get_io_cpus().empty())
				threads[i][j] = std::shared_ptr<pool_task_thread>(
						new pool_task_thread(i * nthreads_per_node + j, name, i));
			else
				threads[i][j] = std::shared_ptr<pool_task_thread>(
						new pool_task_thread(i * nthreads_per_node + j, name,
							cpus, i));
#else
			threads[i][j] = std::shared_ptr<pool_task_thread>(
					new pool_task_thread(i * nthreads_per_node + j, name, i));
#endif
			threads[i][j]->start();
		}
	}
	ntasks_per_node.resize(num_nodes);
}

/*
 * This method dispatches tasks in a round-robin fashion.
 */
void mem_thread_pool::process_task(int node_id, thread_task *task)
{
	if (node_id < 0)
		node_id = tot_num_tasks % get_num_nodes();

	assert((size_t) node_id < threads.size());
	size_t idx = ntasks_per_node[node_id] % threads[node_id].size();
	threads[node_id][idx]->add_task(task);
	ntasks_per_node[node_id]++;
	tot_num_tasks++;
}

void mem_thread_pool::wait4complete()
{
	for (size_t i = 0; i < threads.size(); i++) {
		size_t nthreads = threads[i].size();
		for (size_t j = 0; j < nthreads; j++)
			threads[i][j]->wait4complete();
	}

	// After all workers complete, we should try to clear the memory buffers
	// in each worker thread to reduce memory consumption.
	// We might want to keep the memory buffer for I/O on dense matrices.
	if (matrix_conf.is_keep_mem_buf())
		detail::local_mem_buffer::clear_bufs(
				detail::local_mem_buffer::MAT_PORTION);
	else
		detail::local_mem_buffer::clear_bufs();
}

size_t mem_thread_pool::get_num_pending() const
{
	size_t ret = 0;
	for (size_t i = 0; i < threads.size(); i++) {
		size_t nthreads = threads[i].size();
		for (size_t j = 0; j < nthreads; j++)
			ret += threads[i][j]->get_num_pending();
	}
	return ret;
}

static mem_thread_pool::ptr global_threads;
enum thread_pool_state {
	UNINIT,
	ACTIVE,
	INACTIVE,
};
static thread_pool_state pool_state = thread_pool_state::UNINIT;

/*
 * When we disable thread pool, we use the main thread to perform
 * computation.
 */
bool mem_thread_pool::disable_thread_pool()
{
	pool_state = thread_pool_state::INACTIVE;
	return true;
}

bool mem_thread_pool::enable_thread_pool()
{
	pool_state = thread_pool_state::ACTIVE;
	return true;
}

mem_thread_pool::ptr mem_thread_pool::get_global_mem_threads()
{
	assert(pool_state != thread_pool_state::INACTIVE);
	if (global_threads == NULL) {
		int nthreads_per_node
			= matrix_conf.get_num_DM_threads() / matrix_conf.get_num_nodes();
		assert(nthreads_per_node > 0);
		global_threads = mem_thread_pool::create(matrix_conf.get_num_nodes(),
				nthreads_per_node);
		enable_thread_pool();
	}
	return global_threads;
}

size_t mem_thread_pool::get_global_num_threads()
{
	// When we disable the thread pool, we use the main thread for computation.
	// So the number of threads is 1.
	if (pool_state == thread_pool_state::INACTIVE)
		return 1;
	else
		// We also count the main thread.
		return get_global_mem_threads()->get_num_threads() + 1;
}

int mem_thread_pool::get_curr_thread_id()
{
	// When we disable the thread pool, we use the main thread for computation.
	// And we use 0 as the thread id of the main thread.
	if (pool_state == thread_pool_state::INACTIVE)
		return 0;
	else {
		// It return 0 for the main thread. The worker thread Id starts with 1.
		detail::pool_task_thread *curr
			= dynamic_cast<detail::pool_task_thread *>(thread::get_curr_thread());
		if (curr)
			return curr->get_pool_thread_id() + 1;
		else
			return 0;
	}
}

void mem_thread_pool::init_global_mem_threads(int num_nodes,
		int nthreads_per_node)
{
	if (global_threads == NULL) {
		global_threads = mem_thread_pool::create(num_nodes, nthreads_per_node);
		enable_thread_pool();
	}
}

void mem_thread_pool::destroy()
{
	global_threads = NULL;
}

void io_worker_task::run()
{
	std::vector<safs::io_interface::ptr> ios;
	pthread_spin_lock(&lock);
	for (auto it = EM_objs.begin(); it != EM_objs.end(); it++) {
		std::vector<safs::io_interface::ptr> tmp = (*it)->create_ios();
		ios.insert(ios.end(), tmp.begin(), tmp.end());
	}
	pthread_spin_unlock(&lock);
	safs::io_select::ptr select = safs::create_io_select(ios);

	// The task runs until there are no tasks left in the queue.
	while (dispatch->issue_task())
		safs::wait4ios(select, max_pending_ios);
	// Test if all I/O instances have processed all requests.
	size_t num_pending = safs::wait4ios(select, 0);
	assert(num_pending == 0);

	pthread_spin_lock(&lock);
	EM_objs.clear();
	pthread_spin_unlock(&lock);

	for (size_t i = 0; i < ios.size(); i++) {
		portion_callback &cb = static_cast<portion_callback &>(
				ios[i]->get_callback());
		assert(!cb.has_callback());
	}
}

global_counter::global_counter()
{
	counts.resize(mem_thread_pool::get_global_num_threads());
	reset();
}

void global_counter::inc(size_t val)
{
	int id = mem_thread_pool::get_curr_thread_id();
	counts[id].count += val;
}

void global_counter::reset()
{
	for (size_t i = 0; i < counts.size(); i++)
		counts[i].count = 0;
}

size_t global_counter::get() const
{
	size_t tot = 0;
	for (size_t i = 0; i < counts.size(); i++)
		tot += counts[i].count;
	return tot;
}

}

}
<|endoftext|>


<commit_before>#include <Arduino.h>
#include <roboteqMC.h>

AX2550::AX2550(HardwareSerial& serial_port):uart(serial_port)
{
   uart.begin(9600,SERIAL_7E1);
}

void AX2550::init(uint8_t x,uint8_t y){
   x_key = x;
   y_key = y;
}

void AX2550::set_report(uint8_t v,uint8_t l,uint8_t r){
   volt_key = v;
   amps_left_key = l;
   amps_right_key = r;
}

bool AX2550::move(int Steering,int Throttle, bool check)
{
   int8_t Dir1 = 0;
   int8_t Dir2 = 0;
   while(uart.available()>0)
   {
      uart.read();
   }
   if(Throttle>=0)
   {
      Dir1 = 0x41;
   }
   if(Throttle<0)
   {
      Dir1 = 0x61;
   }
   if(Steering>=0)
   {
      Dir2 = 0x42;
   }
   if(Steering<0)
   {
      Dir2 = 0x62;
   }

   Throttle = map(abs(Throttle),0,100,0,126);

   Steering = map(abs(Steering),0,100,0,126);

   char command[12];
   sprintf(command,"!%c%02x\r\n!%c%02x\r\n",Dir1,abs(Throttle),Dir2,abs(Steering));
   uart.print(command);

   if(check){
      delay(10);

      bool chk_throttle = chkResponse();
      bool chk_steering = chkResponse();

      while(uart.available()>0){
         uart.read();
      }
      return chk_throttle & chk_steering;
   }

   return true;
}

bool AX2550::move(Message inp, bool check){
   if(inp.new_data(y_key) || inp.new_data(x_key)){
      return move(int16_t(inp.get_data(y_key)),int16_t(inp.get_data(x_key)),check);
   }
   return false;
}

bool AX2550::chkResponse()
{
   char status;
   uint8_t counter=0;
   while(1)
   {
      status = uart.read();
      //Serial.print(status);
      if(status == '+')
      {
         return true;
      }
      else if(status == '-')
      {
         //Serial.println("Command Fails!");
         return false;
      }
      else if(counter == 20)
      {
         Serial3.println("Chk response Timeout");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

float AX2550::volt()
{
   while(uart.available())
   {
      uart.read();
   }
   char command[2];
   sprintf(command,"?e");
   if(sendChk(command))
   {
      char inp[2];

      uart.read();
      uart.read();
      uart.read();
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

      float volt = 28.5 * strtoul(inp,0,16)/256;

      // Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }

      return volt;
   }
   return 0.0;
}

int AX2550::amps(uint8_t channel)
{
   while(uart.available())
   {
      uart.read();
   }

   char command[2];
   sprintf(command,"?a");

   if(sendChk(command))
   {
      char inp[2];

     if(channel == 1)
     {
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

     if(channel == 2)
     {
         uart.read();
         uart.read();
         uart.read();
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

      int amps = strtoul(inp,0,16);

      // Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }
      return amps;
   }
   // Serial.println("Fail!");
   return 0;
}

bool AX2550::sendChk(char buff[])
{
   uint8_t lenght = strlen(buff);
   char input_buff[lenght];
   uart.println(buff);

   uint8_t counter=0;
   uint8_t timeout=100;

   delay(10);

   while(1)
   {
      if(uart.available()>0)
      {
         for(int i=0;i<lenght;i++)
         {
            input_buff[i]=uart.read();
            if(input_buff[i]!=buff[i])
            {
               //Echo Condition
               // Serial.println("Echo Error!");
               return false;
            }
         }
         return true;
      }
      else if(counter == timeout)
      {
         //Timeout condition
         // Serial.println("Timeout Error!");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

Message AX2550::report(){
   Message output;
   output.add_data(amps_left_key,uint16_t(amps(1)));
   output.add_data(amps_right_key,uint16_t(amps(2)));
   output.add_data(volt_key,uint16_t(volt()));
   return output;
}<commit_msg>Fix Voltage read function<commit_after>#include <Arduino.h>
#include <roboteqMC.h>

AX2550::AX2550(HardwareSerial& serial_port):uart(serial_port)
{
   uart.begin(9600,SERIAL_7E1);
}

void AX2550::init(uint8_t x,uint8_t y){
   x_key = x;
   y_key = y;
}

void AX2550::set_report(uint8_t v,uint8_t l,uint8_t r){
   volt_key = v;
   amps_left_key = l;
   amps_right_key = r;
}

bool AX2550::move(int Steering,int Throttle, bool check)
{
   int8_t Dir1 = 0;
   int8_t Dir2 = 0;
   while(uart.available()>0)
   {
      uart.read();
   }
   if(Throttle>=0)
   {
      Dir1 = 0x41;
   }
   if(Throttle<0)
   {
      Dir1 = 0x61;
   }
   if(Steering>=0)
   {
      Dir2 = 0x42;
   }
   if(Steering<0)
   {
      Dir2 = 0x62;
   }

   Throttle = map(abs(Throttle),0,100,0,126);

   Steering = map(abs(Steering),0,100,0,126);

   char command[12];
   sprintf(command,"!%c%02x\r\n!%c%02x\r\n",Dir1,abs(Throttle),Dir2,abs(Steering));
   uart.print(command);

   if(check){
      delay(10);

      bool chk_throttle = chkResponse();
      bool chk_steering = chkResponse();

      while(uart.available()>0){
         uart.read();
      }
      return chk_throttle & chk_steering;
   }

   return true;
}

bool AX2550::move(Message inp, bool check){
   if(inp.new_data(y_key) || inp.new_data(x_key)){
      return move(int16_t(inp.get_data(y_key)),int16_t(inp.get_data(x_key)),check);
   }
   return false;
}

bool AX2550::chkResponse()
{
   char status;
   uint8_t counter=0;
   while(1)
   {
      status = uart.read();
      //Serial.print(status);
      if(status == '+')
      {
         return true;
      }
      else if(status == '-')
      {
         //Serial.println("Command Fails!");
         return false;
      }
      else if(counter == 20)
      {
         Serial3.println("Chk response Timeout");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

float AX2550::volt()
{
   while(uart.available())
   {
      uart.read();
   }
   char command[2];
   sprintf(command,"?e");
   if(sendChk(command))
   {
      char inp[4];
/*
      while(uart.available()){
         Serial.println(char(uart.read()));
      }

      uart.read();
      uart.read();
      uart.read();
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

*/
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      uart.read();
      uart.read();
      uart.read();

      uint16_t conv = strtoul(inp,0,16);

      Serial.println(conv);

      float volt = 55 * conv/256.0;

      Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }

      return volt;
   }
   return 0.0;
}

int AX2550::amps(uint8_t channel)
{
   while(uart.available())
   {
      uart.read();
   }

   char command[2];
   sprintf(command,"?a");

   if(sendChk(command))
   {
      char inp[2];

     if(channel == 1)
     {
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

     if(channel == 2)
     {
         uart.read();
         uart.read();
         uart.read();
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

      int amps = strtoul(inp,0,16);

      // Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }
      return amps;
   }
   // Serial.println("Fail!");
   return 0;
}

bool AX2550::sendChk(char buff[])
{
   uint8_t lenght = strlen(buff);
   char input_buff[lenght];
   uart.println(buff);

   uint8_t counter=0;
   uint8_t timeout=100;

   delay(10);

   while(1)
   {
      if(uart.available()>0)
      {
         for(int i=0;i<lenght;i++)
         {
            input_buff[i]=uart.read();
            if(input_buff[i]!=buff[i])
            {
               //Echo Condition
               // Serial.println("Echo Error!");
               return false;
            }
         }
         return true;
      }
      else if(counter == timeout)
      {
         //Timeout condition
         // Serial.println("Timeout Error!");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

Message AX2550::report(){
   Message output;
   output.add_data(amps_left_key,uint16_t(amps(1)));
   output.add_data(amps_right_key,uint16_t(amps(2)));
   output.add_data(volt_key,uint16_t(volt()));
   return output;
}<|endoftext|>


<commit_before>//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

#include <ssl.h>
#include <nanoPAL.h>
#include "mbedtls.h"

int ssl_available_internal(int sd)
{
    mbedTLS_NFContext *context = (mbedTLS_NFContext *)SOCKET_DRIVER.GetSocketSslData(sd);
    mbedtls_ssl_context *ssl = context->ssl;

    // sanity check
    if (ssl == NULL)
    {
        return SOCK_SOCKET_ERROR;
    }

    mbedtls_ssl_read(ssl, NULL, 0);

    if (mbedtls_ssl_check_pending(ssl))
    {
        return mbedtls_ssl_get_bytes_avail(ssl);
    }
    else
    {
        return 0;
    }
}
<commit_msg>Fix call to data available in SSL stream (#1871)<commit_after>//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

#include <ssl.h>
#include <nanoPAL.h>
#include "mbedtls.h"

int ssl_available_internal(int sd)
{
    mbedTLS_NFContext *context = (mbedTLS_NFContext *)SOCKET_DRIVER.GetSocketSslData(sd);
    mbedtls_ssl_context *ssl = context->ssl;

    // sanity check
    if (ssl == NULL)
    {
        return SOCK_SOCKET_ERROR;
    }

    // Developer note
    // Ideally we should be making a call to read passing a NULL pointer and requesting 0 bytes
    // Like this: mbedtls_ssl_read(ssl, NULL, 0)
    // It won't work because we are using blockign sockets.
    // Even if we unblock it temporarily, it will still won't return until there is something to be read.
    // That call will block the execution and the watchdog will eventually kick in.
    // Bottom line: take the information provided by this call as informational.

    int availableBytes = mbedtls_ssl_check_pending(ssl);

    if (availableBytes > 0)
    {
        return mbedtls_ssl_get_bytes_avail(ssl);
    }
    else
    {
        return availableBytes;
    }
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

#include "paddle/framework/backward.h"
#include "paddle/framework/net.h"
#include "paddle/framework/op_registry.h"

namespace paddle {
namespace framework {

static bool AllInSet(const std::vector<std::string>& names,
                     const std::string& suffix,
                     const std::unordered_set<std::string>& set) {
  for (auto& name : names) {
    if (set.find(name + suffix) == set.end()) {
      return false;
    }
  }
  return true;
}

static std::vector<size_t> InSetIdx(
    const std::vector<std::string>& names, const std::string& suffix,
    const std::unordered_set<std::string>& set) {
  std::vector<size_t> ret_val;
  ret_val.reserve(names.size());
  for (size_t i = 0; i < names.size(); ++i) {
    if (set.find(names[i] + suffix) != set.end()) {
      ret_val.push_back(i);
    }
  }
  return ret_val;
}

static std::shared_ptr<OperatorBase> EmptyOp() {
  auto net_op = std::make_shared<NetOp>();
  net_op->CompleteAddOp();
  return net_op;
}

static void DeDuplicate(NetOp* net, std::unordered_se)

    static std::shared_ptr<OperatorBase> BackwardImpl(
        const OperatorBase& forwardOp,
        std::unordered_set<std::string>& no_grad_names, unsigned& uniq_id) {
  if (AllInSet(forwardOp.inputs_, OperatorBase::GRAD_VAR_SUFFIX(),
               no_grad_names)) {
    return EmptyOp();
  }

  if (AllInSet(forwardOp.outputs_, OperatorBase::GRAD_VAR_SUFFIX(),
               no_grad_names)) {
    for (auto& name : forwardOp.inputs_) {
      // Mark all input is not need
      no_grad_names.insert(name + OperatorBase::GRAD_VAR_SUFFIX());
    }
    return EmptyOp();
  }

  auto* net = new NetOp();

  if (forwardOp.IsNetOp()) {
    //! TODO(dzh)
    std::unordered_map<std::string, int> dup_output;
    std::unordered_map<std::string std::vector<int>> dup_output_ops;
    const unsigned uniq_id_local = uniq_id;
    unsigned op_id_offset = 0;
    for (auto& fwd : forwardOp) {
      auto bwd = Backward(fwd, no_grad_names);
      net->AddOp(bwd);
      for (size_t i = 0; i < bwd.outputs_; ++i) {
        bwd->outputs_[i] += OperatorBase::EMPTY_VAR_NAME();
        if (dup_output.find(bwd->inputs_[i]) == dup_output.end()) {
          dup_output[bwd->inputs_[i]] = 1;
          dup_output_ops[bwd->inputs_[i]] = std::vector<int>{op_id_offset++};
        } else {
          dup_output[bwd->inputs_[i]]++;
          dup_output_ops[bwd->inputs_[i]].emplace_back(op_id_offset++);
        }
      }
    }
    for (auto dup : dup_output) {
      if (dup.second == 1) continue;
      auto op_ids = dup_output_ops.at(dup.first);
      for (auto& op_id : op_ids) {
        auto& op_ptr = net->ops_[op_id];
        for (size_t i = 0; i < op_ptr->inputs_.size(); ++i) {
          if (op_ptr->inputs_[i] == dup.first) {
            // unique the duplicate name
            op_ptr->inputs_[i] += std::to_string(uniq_id++);
            // TODO(dzh): need a generic add op here
          }
        }
      }
    }

  } else {
    //! TODO(fjy)
    std::shared_ptr<OperatorBase> grad_op = OpRegistry::CreateGradOp(forwardOp);
    for (std::string& grad_input : grad_op->inputs_) {
      if (no_grad_names.count(grad_input)) {
        std::string prefix = grad_input.substr(
            0, grad_input.size() - OperatorBase::GRAD_VAR_SUFFIX().size());
        grad_input = prefix + OperatorBase::ZERO_VAR_SUFFIX();
        net->AddOp(OpRegistry::CreateOp("fill_zeros_like", {prefix},
                                        {grad_input}, {}));
      }
    }
    for (std::string& grad_output : grad_op->outputs_) {
      if (no_grad_names.count(grad_output)) {
        grad_output = OperatorBase::EMPTY_VAR_NAME();
      }
    }
    net->AddOp(grad_op);
  }

  net->CompleteAddOp();
  return std::shared_ptr<OperatorBase>(net);
}

extern std::shared_ptr<OperatorBase> Backward(
    const OperatorBase& forwardOp,
    const std::unordered_set<std::string>& no_grad_vars) {
  std::unordered_set<std::string> no_grad_names;
  no_grad_names.reserve(no_grad_vars.size());

  for (auto& name : no_grad_vars) {
    no_grad_names.insert(name + OperatorBase::GRAD_VAR_SUFFIX());
  }
  int uid = 0;
  return BackwardImpl(forwardOp, no_grad_names, uid);
}
}  // namespace framework
}  // namespace paddle
<commit_msg>Fix compile error<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

#include "paddle/framework/backward.h"
#include "paddle/framework/net.h"
#include "paddle/framework/op_registry.h"

namespace paddle {
namespace framework {

static bool AllInSet(const std::vector<std::string>& names,
                     const std::string& suffix,
                     const std::unordered_set<std::string>& set) {
  for (auto& name : names) {
    if (set.find(name + suffix) == set.end()) {
      return false;
    }
  }
  return true;
}

static std::vector<size_t> InSetIdx(
    const std::vector<std::string>& names, const std::string& suffix,
    const std::unordered_set<std::string>& set) {
  std::vector<size_t> ret_val;
  ret_val.reserve(names.size());
  for (size_t i = 0; i < names.size(); ++i) {
    if (set.find(names[i] + suffix) != set.end()) {
      ret_val.push_back(i);
    }
  }
  return ret_val;
}

static std::shared_ptr<OperatorBase> EmptyOp() {
  auto net_op = std::make_shared<NetOp>();
  net_op->CompleteAddOp();
  return net_op;
}

static std::shared_ptr<OperatorBase> BackwardImpl(
    const OperatorBase& forwardOp,
    std::unordered_set<std::string>& no_grad_names, size_t& uniq_id) {
  if (AllInSet(forwardOp.inputs_, OperatorBase::GRAD_VAR_SUFFIX(),
               no_grad_names)) {
    return EmptyOp();
  }

  if (AllInSet(forwardOp.outputs_, OperatorBase::GRAD_VAR_SUFFIX(),
               no_grad_names)) {
    for (auto& name : forwardOp.inputs_) {
      // Mark all input is not need
      no_grad_names.insert(name + OperatorBase::GRAD_VAR_SUFFIX());
    }
    return EmptyOp();
  }

  auto* net = new NetOp();

  if (forwardOp.IsNetOp()) {
    //! TODO(dzh)
    std::unordered_map<std::string, int> dup_output;
    std::unordered_map<std::string, std::vector<int>> dup_output_ops;
    //    const unsigned uniq_id_local = uniq_id;
    int op_id_offset = 0;
    // Because it is a net op, it can static_cast.
    auto& forwardNet = static_cast<const NetOp&>(forwardOp);

    for (auto& fwd : forwardNet.ops_) {
      auto bwd = Backward(*fwd, no_grad_names);
      net->AddOp(bwd);
      for (size_t i = 0; i < bwd->outputs_.size(); ++i) {
        bwd->outputs_[i] += OperatorBase::EMPTY_VAR_NAME();
        if (dup_output.find(bwd->inputs_[i]) == dup_output.end()) {
          dup_output[bwd->inputs_[i]] = 1;
          dup_output_ops[bwd->inputs_[i]] = std::vector<int>{op_id_offset++};
        } else {
          dup_output[bwd->inputs_[i]]++;
          dup_output_ops[bwd->inputs_[i]].emplace_back(op_id_offset++);
        }
      }
    }
    for (auto dup : dup_output) {
      if (dup.second == 1) continue;
      auto op_ids = dup_output_ops.at(dup.first);
      for (auto& op_id : op_ids) {
        auto& op_ptr = net->ops_[op_id];
        for (size_t i = 0; i < op_ptr->inputs_.size(); ++i) {
          if (op_ptr->inputs_[i] == dup.first) {
            // unique the duplicate name
            op_ptr->inputs_[i] += std::to_string(uniq_id++);
            // TODO(dzh): need a generic add op here
          }
        }
      }
    }

  } else {
    //! TODO(fjy)
    std::shared_ptr<OperatorBase> grad_op = OpRegistry::CreateGradOp(forwardOp);
    for (std::string& grad_input : grad_op->inputs_) {
      if (no_grad_names.count(grad_input)) {
        std::string prefix = grad_input.substr(
            0, grad_input.size() - OperatorBase::GRAD_VAR_SUFFIX().size());
        grad_input = prefix + OperatorBase::ZERO_VAR_SUFFIX();
        net->AddOp(OpRegistry::CreateOp("fill_zeros_like", {prefix},
                                        {grad_input}, {}));
      }
    }
    for (std::string& grad_output : grad_op->outputs_) {
      if (no_grad_names.count(grad_output)) {
        grad_output = OperatorBase::EMPTY_VAR_NAME();
      }
    }
    net->AddOp(grad_op);
  }

  net->CompleteAddOp();
  return std::shared_ptr<OperatorBase>(net);
}

extern std::shared_ptr<OperatorBase> Backward(
    const OperatorBase& forwardOp,
    const std::unordered_set<std::string>& no_grad_vars) {
  std::unordered_set<std::string> no_grad_names;
  no_grad_names.reserve(no_grad_vars.size());

  for (auto& name : no_grad_vars) {
    no_grad_names.insert(name + OperatorBase::GRAD_VAR_SUFFIX());
  }
  size_t uid = 0;
  return BackwardImpl(forwardOp, no_grad_names, uid);
}
}  // namespace framework
}  // namespace paddle
<|endoftext|>