<commit_before>#include "panel.h"
#include "component.h"
#include "flowlayout.h"
#include "frame.h"

#include <list>
#include <cassert>

namespace gui {

	Panel::Panel() : mouseMotionInsideComponent_(false), mouseDownInsideComponent_(false), layoutManager_(std::make_shared<FlowLayout>()) {
		setPreferredSize(50, 50);
		setBorderColor(1, 1, 1, 0);
	}

	void Panel::setChildsParent() {
	    for (auto& c : components_) {
			c->parent_ = std::static_pointer_cast<Panel>(shared_from_this());
			if (ancestor_ != nullptr) {
				c->ancestor_ = ancestor_;
			} else {
				c->ancestor_ = c->parent_;
			}
			c->setChildsParent();
		}
	}

	std::shared_ptr<Component> Panel::addDefault(const std::shared_ptr<Component>& component) {
		add(DEFAULT_INDEX, component);
		return component;
	}

    std::shared_ptr<Component> Panel::add(int layoutIndex, const std::shared_ptr<Component>& component) {
		// Was already added?
		assert(!component->isAdded_);
		component->isAdded_ = true;
		component->setLayoutIndex(layoutIndex);
		components_.push_back(component);
		setChildsParent();
		if (component->isGrabFocus()) {
			setFocus(true);
			++nbrChildGrabFocus_;
		}
		validate();
		return component;
	}

	std::shared_ptr<Component> Panel::addDefaultToGroup(const std::shared_ptr<Component>& component) {
		add(DEFAULT_INDEX, component);
		group_.add(component);
		return component;
	}

	std::shared_ptr<Component> Panel::addToGroup(int layoutIndex, const std::shared_ptr<Component>& component) {
		add(layoutIndex, component);
		group_.add(component);
		return component;
	}

	std::shared_ptr<LayoutManager> Panel::setLayout(const std::shared_ptr<LayoutManager>& layoutManager) {
		layoutManager_ = layoutManager;
		return layoutManager_;
	}

	void Panel::setFocus(bool focus) {
		Component::setFocus(focus);
		if (!focus) {
			for (auto& component : *this) {
				component->setFocus(false);
			}
		}
	}

	std::shared_ptr<LayoutManager> Panel::getLayout() const {
		return layoutManager_;
	}

	std::vector<std::shared_ptr<Component>>::iterator Panel::begin() {
		return components_.begin();
	}

	std::vector<std::shared_ptr<Component>>::iterator Panel::end() {
		return components_.end();
	}

	const std::vector<std::shared_ptr<Component>>& Panel::getComponents() const {
		return components_;
	}

	void Panel::draw(const Graphic& graphic, double deltaTime) {
		graphic.useProgram();
		graphic.setModel(Component::model_);
		Component::draw(graphic, deltaTime);

		// Draw the components.
		for (auto& component : *this) {
			if (component->isVisible()) {
				graphic.useProgram();
				graphic.setModel(component->model_);
				component->draw(graphic, deltaTime);
			}
		}
	}

	void Panel::handleMouse(const SDL_Event& mouseEvent) {
		std::shared_ptr<Component> currentComponent;
		switch (mouseEvent.type) {
			case SDL_MOUSEMOTION:
				for (auto& component : *this) {
					if (!component->isVisible()) {
						continue;
					}
					Point p = component->getLocation();
					Dimension d = component->getSize();
					if (p.x_ <= mouseEvent.motion.x && p.x_ + d.width_ > mouseEvent.motion.x &&
						p.y_ <= mouseEvent.motion.y && p.y_ + d.height_ > mouseEvent.motion.y) {
						SDL_Event motionEvent = mouseEvent;
						motionEvent.motion.x -= (Sint32) p.x_;
						motionEvent.motion.y -= (Sint32) p.y_;
						component->handleMouse(motionEvent);
						currentComponent = component;
						break;
					}
				}
				if (mouseMotionInsideComponent_ != currentComponent) {
					if (mouseMotionInsideComponent_ != nullptr) {
						mouseMotionInsideComponent_->mouseMotionLeave();
					}
				}
				mouseMotionInsideComponent_ = currentComponent;
				Component::handleMouse(mouseEvent);
				break;
			case SDL_MOUSEBUTTONDOWN:
				// Fall through!
			case SDL_MOUSEBUTTONUP:
				// Send the mouseEvent through to the correct component.
				for (auto& component : *this) {
					if (!component->isVisible()) {
						continue;
					}
					Point p = component->getLocation();
					Dimension d = component->getSize();

					// Mouse is inside the component?
					if (p.x_ <= mouseEvent.button.x && p.x_ + d.width_ > mouseEvent.button.x &&
						p.y_ <= mouseEvent.button.y && p.y_ + d.height_ > mouseEvent.button.y) {
						SDL_Event buttonEvent = mouseEvent;
						buttonEvent.motion.x -= (Sint32) p.x_;
						buttonEvent.motion.y -= (Sint32) p.y_;
						currentComponent = component;
						component->handleMouse(buttonEvent);
						break; // Abort, components should not overlap!
					}
				}

				if (mouseEvent.type == SDL_MOUSEBUTTONDOWN) {
					// Set all components focus to false except
					// the component used.
					for (auto& component : *this) {
						if (!component->isVisible()) {
							continue;
						}
						if (currentComponent == component) {
							component->setFocus(true);
						} else {
							component->setFocus(false);
						}
					}
				}

				// Call the component if it was pushed and released outside
				// the component.
				if (mouseEvent.type == SDL_MOUSEBUTTONUP) {
					if (mouseDownInsideComponent_ != nullptr && mouseDownInsideComponent_ != currentComponent) {
						mouseDownInsideComponent_->mouseOutsideUp();
						mouseDownInsideComponent_ = nullptr;
					}
				} else if (mouseEvent.type == SDL_MOUSEBUTTONDOWN) {
					mouseDownInsideComponent_ = currentComponent;
				}

				Component::handleMouse(mouseEvent);
				break;
		}
	}

	void Panel::handleKeyboard(const SDL_Event& keyEvent) {
		for (auto& component : *this) {
			if (component->hasFocus()) {
				component->handleKeyboard(keyEvent);
			}
		}
		Component::handleKeyboard(keyEvent);
		group_.handleKeyboard(keyEvent);
	}

	void Panel::mouseMotionLeave() {
		for (auto& component : *this) {
			component->mouseMotionLeave();
		}
	}

	void Panel::mouseOutsideUp() {
		for (auto& component : *this) {
			component->mouseOutsideUp();
		}
	}

	void Panel::panelChanged(bool active) {
		if (active) {
			validate();
		}

		for (auto& component : *this) {
			component->panelChanged(active);
		}
		Component::panelChanged(active);
	}

	void Panel::validate() {
		// Validate!
		layoutManager_->layoutContainer(*this);
		for (auto& child : *this) {
			child->validate();
		}

		group_.sort();
	}

	mw::signals::Connection Panel::addDrawListener(const DrawListener::Callback& callback) {
		return drawListener_.connect(callback);
	}

	void Panel::drawFirst(Frame& frame, const Graphic& graphic, double deltaTime) {
		graphic.useProgram();
		graphic.setModel(Component::model_);
		drawListener_(frame, deltaTime);
		for (auto& child : *this) {
			graphic.useProgram();
			graphic.setModel(child->model_);
			child->drawFirst(frame, graphic, deltaTime);
		}
	}

	void Panel::drawLast(Frame& frame, const Graphic& graphic, double deltaTime) {
		for (auto& child : *this) {
			graphic.useProgram();
			graphic.setModel(child->model_);
			child->drawLast(frame, graphic, deltaTime);
		}
	}

} // Namespace gui.
<commit_msg>Fixed incorrect initialization of shared_ptr.<commit_after>#include "panel.h"
#include "component.h"
#include "flowlayout.h"
#include "frame.h"

#include <list>
#include <cassert>

namespace gui {

	Panel::Panel() : layoutManager_(std::make_shared<FlowLayout>()) {
		setPreferredSize(50, 50);
		setBorderColor(1, 1, 1, 0);
	}

	void Panel::setChildsParent() {
	    for (auto& c : components_) {
			c->parent_ = std::static_pointer_cast<Panel>(shared_from_this());
			if (ancestor_ != nullptr) {
				c->ancestor_ = ancestor_;
			} else {
				c->ancestor_ = c->parent_;
			}
			c->setChildsParent();
		}
	}

	std::shared_ptr<Component> Panel::addDefault(const std::shared_ptr<Component>& component) {
		add(DEFAULT_INDEX, component);
		return component;
	}

    std::shared_ptr<Component> Panel::add(int layoutIndex, const std::shared_ptr<Component>& component) {
		// Was already added?
		assert(!component->isAdded_);
		component->isAdded_ = true;
		component->setLayoutIndex(layoutIndex);
		components_.push_back(component);
		setChildsParent();
		if (component->isGrabFocus()) {
			setFocus(true);
			++nbrChildGrabFocus_;
		}
		validate();
		return component;
	}

	std::shared_ptr<Component> Panel::addDefaultToGroup(const std::shared_ptr<Component>& component) {
		add(DEFAULT_INDEX, component);
		group_.add(component);
		return component;
	}

	std::shared_ptr<Component> Panel::addToGroup(int layoutIndex, const std::shared_ptr<Component>& component) {
		add(layoutIndex, component);
		group_.add(component);
		return component;
	}

	std::shared_ptr<LayoutManager> Panel::setLayout(const std::shared_ptr<LayoutManager>& layoutManager) {
		layoutManager_ = layoutManager;
		return layoutManager_;
	}

	void Panel::setFocus(bool focus) {
		Component::setFocus(focus);
		if (!focus) {
			for (auto& component : *this) {
				component->setFocus(false);
			}
		}
	}

	std::shared_ptr<LayoutManager> Panel::getLayout() const {
		return layoutManager_;
	}

	std::vector<std::shared_ptr<Component>>::iterator Panel::begin() {
		return components_.begin();
	}

	std::vector<std::shared_ptr<Component>>::iterator Panel::end() {
		return components_.end();
	}

	const std::vector<std::shared_ptr<Component>>& Panel::getComponents() const {
		return components_;
	}

	void Panel::draw(const Graphic& graphic, double deltaTime) {
		graphic.useProgram();
		graphic.setModel(Component::model_);
		Component::draw(graphic, deltaTime);

		// Draw the components.
		for (auto& component : *this) {
			if (component->isVisible()) {
				graphic.useProgram();
				graphic.setModel(component->model_);
				component->draw(graphic, deltaTime);
			}
		}
	}

	void Panel::handleMouse(const SDL_Event& mouseEvent) {
		std::shared_ptr<Component> currentComponent;
		switch (mouseEvent.type) {
			case SDL_MOUSEMOTION:
				for (auto& component : *this) {
					if (!component->isVisible()) {
						continue;
					}
					Point p = component->getLocation();
					Dimension d = component->getSize();
					if (p.x_ <= mouseEvent.motion.x && p.x_ + d.width_ > mouseEvent.motion.x &&
						p.y_ <= mouseEvent.motion.y && p.y_ + d.height_ > mouseEvent.motion.y) {
						SDL_Event motionEvent = mouseEvent;
						motionEvent.motion.x -= (Sint32) p.x_;
						motionEvent.motion.y -= (Sint32) p.y_;
						component->handleMouse(motionEvent);
						currentComponent = component;
						break;
					}
				}
				if (mouseMotionInsideComponent_ != currentComponent) {
					if (mouseMotionInsideComponent_ != nullptr) {
						mouseMotionInsideComponent_->mouseMotionLeave();
					}
				}
				mouseMotionInsideComponent_ = currentComponent;
				Component::handleMouse(mouseEvent);
				break;
			case SDL_MOUSEBUTTONDOWN:
				// Fall through!
			case SDL_MOUSEBUTTONUP:
				// Send the mouseEvent through to the correct component.
				for (auto& component : *this) {
					if (!component->isVisible()) {
						continue;
					}
					Point p = component->getLocation();
					Dimension d = component->getSize();

					// Mouse is inside the component?
					if (p.x_ <= mouseEvent.button.x && p.x_ + d.width_ > mouseEvent.button.x &&
						p.y_ <= mouseEvent.button.y && p.y_ + d.height_ > mouseEvent.button.y) {
						SDL_Event buttonEvent = mouseEvent;
						buttonEvent.motion.x -= (Sint32) p.x_;
						buttonEvent.motion.y -= (Sint32) p.y_;
						currentComponent = component;
						component->handleMouse(buttonEvent);
						break; // Abort, components should not overlap!
					}
				}

				if (mouseEvent.type == SDL_MOUSEBUTTONDOWN) {
					// Set all components focus to false except
					// the component used.
					for (auto& component : *this) {
						if (!component->isVisible()) {
							continue;
						}
						if (currentComponent == component) {
							component->setFocus(true);
						} else {
							component->setFocus(false);
						}
					}
				}

				// Call the component if it was pushed and released outside
				// the component.
				if (mouseEvent.type == SDL_MOUSEBUTTONUP) {
					if (mouseDownInsideComponent_ != nullptr && mouseDownInsideComponent_ != currentComponent) {
						mouseDownInsideComponent_->mouseOutsideUp();
						mouseDownInsideComponent_ = nullptr;
					}
				} else if (mouseEvent.type == SDL_MOUSEBUTTONDOWN) {
					mouseDownInsideComponent_ = currentComponent;
				}

				Component::handleMouse(mouseEvent);
				break;
		}
	}

	void Panel::handleKeyboard(const SDL_Event& keyEvent) {
		for (auto& component : *this) {
			if (component->hasFocus()) {
				component->handleKeyboard(keyEvent);
			}
		}
		Component::handleKeyboard(keyEvent);
		group_.handleKeyboard(keyEvent);
	}

	void Panel::mouseMotionLeave() {
		for (auto& component : *this) {
			component->mouseMotionLeave();
		}
	}

	void Panel::mouseOutsideUp() {
		for (auto& component : *this) {
			component->mouseOutsideUp();
		}
	}

	void Panel::panelChanged(bool active) {
		if (active) {
			validate();
		}

		for (auto& component : *this) {
			component->panelChanged(active);
		}
		Component::panelChanged(active);
	}

	void Panel::validate() {
		// Validate!
		layoutManager_->layoutContainer(*this);
		for (auto& child : *this) {
			child->validate();
		}

		group_.sort();
	}

	mw::signals::Connection Panel::addDrawListener(const DrawListener::Callback& callback) {
		return drawListener_.connect(callback);
	}

	void Panel::drawFirst(Frame& frame, const Graphic& graphic, double deltaTime) {
		graphic.useProgram();
		graphic.setModel(Component::model_);
		drawListener_(frame, deltaTime);
		for (auto& child : *this) {
			graphic.useProgram();
			graphic.setModel(child->model_);
			child->drawFirst(frame, graphic, deltaTime);
		}
	}

	void Panel::drawLast(Frame& frame, const Graphic& graphic, double deltaTime) {
		for (auto& child : *this) {
			graphic.useProgram();
			graphic.setModel(child->model_);
			child->drawLast(frame, graphic, deltaTime);
		}
	}

} // Namespace gui.
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <pthread.h>
#include <unistd.h>

#include "../../cvmfs/util_concurrency.h"

class T_BlockingCounter : public ::testing::Test {
 protected:
  T_BlockingCounter() : max_value_(100),
                        uint_counter_(max_value_) {}

  virtual void SetUp() {}

  static void *concurrent_incrementer(void *counter) {
    BlockingCounter<unsigned int> &cntr =
      *static_cast<BlockingCounter<unsigned int>*>(counter);

    T_BlockingCounter::concurrent_state_ = 1;
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 2;

    return NULL;
  }

  static void *concurrent_zero_waiter(void *counter) {
    BlockingCounter<unsigned int> &cntr =
      *static_cast<BlockingCounter<unsigned int>*>(counter);

    cntr.WaitForZero();
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 1;

    cntr.WaitForZero();
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 2;

    cntr.WaitForZero();
    T_BlockingCounter::concurrent_state_ = 3;

    return NULL;
  }

 protected:
  unsigned int max_value_;
  BlockingCounter<unsigned int> uint_counter_;
  static int concurrent_state_;
};

int T_BlockingCounter::concurrent_state_ = 0;

TEST_F(T_BlockingCounter, Initialize) {
  EXPECT_EQ (  0u, uint_counter_);
  EXPECT_EQ (100u, uint_counter_.MaximalValue());
}

TEST_F(T_BlockingCounter, Increment) {
  const unsigned int postcrement = uint_counter_++;
  EXPECT_EQ (1u, uint_counter_);
  EXPECT_EQ (0u, postcrement);

  const unsigned int precrement = ++uint_counter_;
  EXPECT_EQ (2u, uint_counter_);
  EXPECT_EQ (2u, precrement);

  uint_counter_.Increment();
  EXPECT_EQ (3u, uint_counter_);
}

TEST_F(T_BlockingCounter, Assignment) {
  const unsigned int val = max_value_ / 2;
  uint_counter_ = val;
  EXPECT_EQ (val, uint_counter_);
}

TEST_F(T_BlockingCounter, Decrement) {
  const unsigned int val = max_value_ / 2;
  uint_counter_ = val;

  const unsigned int postcrement = uint_counter_--;
  EXPECT_EQ (val - 1, uint_counter_);
  EXPECT_EQ (val,     postcrement);

  const unsigned int precrement = --uint_counter_;
  EXPECT_EQ (val - 2, uint_counter_);
  EXPECT_EQ (val - 2, precrement);

  uint_counter_.Decrement();
  EXPECT_EQ (val - 3, uint_counter_);
}

TEST_F(T_BlockingCounter, IncrementAndWait) {
  uint_counter_ = max_value_;

  T_BlockingCounter::concurrent_state_ = 0;
  EXPECT_EQ (0, T_BlockingCounter::concurrent_state_);

  pthread_t thread;
  const int res = pthread_create(&thread,
                                  NULL,
                                 &T_BlockingCounter::concurrent_incrementer,
                                  static_cast<void*>(&uint_counter_));
  ASSERT_EQ (0, res);

  sleep(1);
  EXPECT_EQ (1, T_BlockingCounter::concurrent_state_);

  --uint_counter_;
  sleep(1);
  EXPECT_EQ (2,          T_BlockingCounter::concurrent_state_);
  EXPECT_EQ (max_value_, uint_counter_);

  const int killed = pthread_kill(thread, 0);
  EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
  if (killed == ESRCH) {
    pthread_cancel(thread);
  }
}

TEST_F(T_BlockingCounter, BecomeZero) {
  T_BlockingCounter::concurrent_state_ = 0;
  EXPECT_EQ (0, T_BlockingCounter::concurrent_state_);

  ASSERT_EQ (0u, uint_counter_);
  pthread_t thread;
  const int res = pthread_create(&thread,
                                  NULL,
                                 &T_BlockingCounter::concurrent_zero_waiter,
                                  static_cast<void*>(&uint_counter_));
  ASSERT_EQ (0, res);

  sleep(1);
  EXPECT_EQ (1,  T_BlockingCounter::concurrent_state_) << "Waited, even though "
                                                       << "counter was zero!";
  EXPECT_NE (0u, uint_counter_);

  uint_counter_ = 1u;
  --uint_counter_;
  EXPECT_EQ (0u, uint_counter_);
  sleep(1);
  EXPECT_EQ (2,  T_BlockingCounter::concurrent_state_) << "Thread did not wake "
                                                       << "up for zero counter!";
  EXPECT_NE (0u, uint_counter_);

  uint_counter_ = 0u;
  EXPECT_EQ (0u, uint_counter_);
  sleep(1);
  EXPECT_EQ (3,  T_BlockingCounter::concurrent_state_) << "Thread didn't wake up "
                                                       << "for zero'ed counter!";

  const int killed = pthread_kill(thread, 0);
  EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
  if (killed == ESRCH) {
    pthread_cancel(thread);
  }
}
<commit_msg>adapt test case for BlockingCounter<commit_after>#include <gtest/gtest.h>
#include <pthread.h>
#include <unistd.h>

#include "../../cvmfs/util_concurrency.h"

class T_BlockingCounter : public ::testing::Test {
 protected:
  T_BlockingCounter() : max_value_(100),
                        int_counter_(max_value_) {}

  virtual void SetUp() {}

  static void *concurrent_incrementer(void *counter) {
    BlockingIntCounter &cntr =
      *static_cast<BlockingIntCounter*>(counter);

    T_BlockingCounter::concurrent_state_ = 1;
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 2;

    return NULL;
  }

  static void *concurrent_zero_waiter(void *counter) {
    BlockingIntCounter &cntr =
      *static_cast<BlockingIntCounter*>(counter);

    cntr.WaitForZero();
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 1;

    cntr.WaitForZero();
    ++cntr;
    T_BlockingCounter::concurrent_state_ = 2;

    cntr.WaitForZero();
    T_BlockingCounter::concurrent_state_ = 3;

    return NULL;
  }

 protected:
  int max_value_;
  BlockingIntCounter int_counter_;
  static int concurrent_state_;
};

int T_BlockingCounter::concurrent_state_ = 0;

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

TEST_F(T_BlockingCounter, Initialize) {
  EXPECT_EQ (  0, int_counter_);
  EXPECT_EQ (100, int_counter_.MaximalValue());
}

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

TEST_F(T_BlockingCounter, Increment) {
  const int postcrement = int_counter_++;
  EXPECT_EQ (1, int_counter_);
  EXPECT_EQ (0, postcrement);

  const int precrement = ++int_counter_;
  EXPECT_EQ (2, int_counter_);
  EXPECT_EQ (2, precrement);

  int_counter_.Increment();
  EXPECT_EQ (3, int_counter_);
}

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

TEST_F(T_BlockingCounter, Assignment) {
  const int val = max_value_ / 2;
  int_counter_ = val;
  EXPECT_EQ (val, int_counter_);
}

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

TEST_F(T_BlockingCounter, Decrement) {
  const int val = max_value_ / 2;
  int_counter_ = val;

  const int postcrement = int_counter_--;
  EXPECT_EQ (val - 1, int_counter_);
  EXPECT_EQ (val,     postcrement);

  const int precrement = --int_counter_;
  EXPECT_EQ (val - 2, int_counter_);
  EXPECT_EQ (val - 2, precrement);

  int_counter_.Decrement();
  EXPECT_EQ (val - 3, int_counter_);
}

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

TEST_F(T_BlockingCounter, IncrementAndWait) {
  int_counter_ = max_value_;

  T_BlockingCounter::concurrent_state_ = 0;
  EXPECT_EQ (0, T_BlockingCounter::concurrent_state_);

  pthread_t thread;
  const int res = pthread_create(&thread,
                                  NULL,
                                 &T_BlockingCounter::concurrent_incrementer,
                                  static_cast<void*>(&int_counter_));
  ASSERT_EQ (0, res);

  sleep(1);
  EXPECT_EQ (1, T_BlockingCounter::concurrent_state_);

  --int_counter_;
  sleep(1);
  EXPECT_EQ (2,          T_BlockingCounter::concurrent_state_);
  EXPECT_EQ (max_value_, int_counter_);

  const int killed = pthread_kill(thread, 0);
  EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
  if (killed != ESRCH) {
    pthread_cancel(thread);
  } else {
    pthread_join(thread, NULL);
  }
}

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

TEST_F(T_BlockingCounter, BecomeZero) {
  T_BlockingCounter::concurrent_state_ = 0;
  EXPECT_EQ (0, T_BlockingCounter::concurrent_state_);

  ASSERT_EQ (0, int_counter_);
  pthread_t thread;
  const int res = pthread_create(&thread,
                                  NULL,
                                 &T_BlockingCounter::concurrent_zero_waiter,
                                  static_cast<void*>(&int_counter_));
  ASSERT_EQ (0, res);

  sleep(1);
  EXPECT_EQ (1,  T_BlockingCounter::concurrent_state_) << "Waited, even though "
                                                       << "counter was zero!";
  EXPECT_NE (0, int_counter_);

  int_counter_ = 1;
  --int_counter_;
  EXPECT_EQ (0, int_counter_);
  sleep(1);
  EXPECT_EQ (2,  T_BlockingCounter::concurrent_state_) << "Thread did not wake "
                                                       << "up for zero counter!";
  EXPECT_NE (0, int_counter_);

  int_counter_ = 0;
  EXPECT_EQ (0, int_counter_);
  sleep(1);
  EXPECT_EQ (3,  T_BlockingCounter::concurrent_state_) << "Thread didn't wake up "
                                                       << "for zero'ed counter!";

  const int killed = pthread_kill(thread, 0);
  EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
  if (killed != ESRCH) {
    pthread_cancel(thread);
  }
}
<|endoftext|>


<commit_before>/**
 * @file       BlynkDebug.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2015
 * @brief      Debug utilities for Arduino
 */
#include <Blynk/BlynkDebug.h>

#if defined(ARDUINO) && defined(__AVR__) && defined(BLYNK_USE_AVR_WDT)

    #include <Arduino.h>
    #include <avr/wdt.h>

    void BlynkSystemInit(void) __attribute__((naked)) __attribute__((section(".init3")));

    void BlynkSystemInit(void)
    {
        MCUSR = 0;
        wdt_disable();
    }

    void BlynkReset()
    {
        wdt_enable(WDTO_15MS);
        delay(50);
        void(*resetFunc)(void) = 0;
        resetFunc();
        for(;;) {} // To make compiler happy
    }

    size_t BlynkFreeRam()
    {
        extern int __heap_start, *__brkval;
        int v;
        return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && defined(__AVR__)

    #include <Arduino.h>

    void BlynkReset()
    {
        void(*resetFunc)(void) = 0;
        resetFunc();
        for(;;) {}
    }

    size_t BlynkFreeRam()
    {
        extern int __heap_start, *__brkval;
        int v;
        return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && defined(ESP8266)

    #include <Arduino.h>

    size_t BlynkFreeRam()
    {
        return ESP.getFreeHeap();
    }

    void BlynkReset()
    {
        ESP.restart();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)

    #include <Arduino.h>

    size_t BlynkFreeRam()
    {
        return 0;
    }

    void BlynkReset()
    {
        NVIC_SystemReset();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined (ARDUINO_ARCH_ARC32)

    millis_time_t BlynkMillis()
    {
        // TODO: Remove workaround for Intel Curie
        // https://forum.arduino.cc/index.php?topic=391836.0
        noInterrupts();
        uint64_t t = millis();
        interrupts();
        return t;
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && (defined(__STM32F1__) || defined(__STM32F3__))

    #include <Arduino.h>
    #include <libmaple/nvic.h>

    size_t BlynkFreeRam()
    {
        return 0;
    }

    void BlynkReset()
    {
        nvic_sys_reset();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined (PARTICLE) || defined(SPARK)

    #include "application.h"

    size_t BlynkFreeRam()
    {
        return 0;
    }

    void BlynkReset()
    {
        System.reset();
        for(;;) {} // To make compiler happy
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ENERGIA)

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(MBED_LIBRARY_VERSION)

    #include "mbed.h"

    static Timer  blynk_millis_timer;
    static Ticker blynk_waker;

    static
    void blynk_wake() {
        //pc.puts("(...)");
    }

    void BlynkSystemInit(void) __attribute__((naked)) __attribute__((section(".init3")));

    void BlynkSystemInit(void)
    {
        blynk_waker.attach(&blynk_wake, 2.0);
        blynk_millis_timer.start();
    }

    void BlynkDelay(millis_time_t ms)
    {
        wait_ms(ms);
    }

    millis_time_t BlynkMillis()
    {
        return blynk_millis_timer.read_ms();
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET

#elif defined(LINUX) && defined(RASPBERRY)
    #include <stdlib.h>
    #include <wiringPi.h>

    void BlynkSystemInit(void)
    {
        wiringPiSetupGpio();
    }

    void BlynkReset()
    {
        exit(1);
        for(;;) {} // To make compiler happy
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(LINUX)

    #define _POSIX_C_SOURCE 200809L
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>

    void BlynkReset()
    {
        exit(1);
        for(;;) {} // To make compiler happy
    }

    void BlynkDelay(millis_time_t ms)
    {
        usleep(ms * 1000);
    }

    millis_time_t BlynkMillis()
    {
        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts );
        return ( ts.tv_sec * 1000 + ts.tv_nsec / 1000000L );
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM

#else

    #if defined(BLYNK_DEBUG_ALL)
        #warning "Need to implement board-specific utilities"
    #endif

    size_t BlynkFreeRam()
    {
        return 0;
    }

    void BlynkReset()
    {
        for(;;) {} // To make compiler happy
    }

#endif

#ifdef _BLYNK_USE_DEFAULT_DELAY
    void BlynkDelay(millis_time_t ms)
    {
        return delay(ms);
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_MILLIS
    millis_time_t BlynkMillis()
    {
        return millis();
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_FREE_RAM
    size_t BlynkFreeRam()
    {
        return 0;
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_RESET
    void BlynkReset()
    {
        for(;;) {} // To make compiler happy
    }
#endif

void BlynkFatal()
{
    BlynkDelay(10000L);
    BlynkReset();
}

<commit_msg>Fix build<commit_after>/**
 * @file       BlynkDebug.cpp
 * @author     Volodymyr Shymanskyy
 * @license    This project is released under the MIT License (MIT)
 * @copyright  Copyright (c) 2015 Volodymyr Shymanskyy
 * @date       Jan 2015
 * @brief      Debug utilities for Arduino
 */
#include <Blynk/BlynkDebug.h>

#if defined(ARDUINO) && defined(__AVR__) && defined(BLYNK_USE_AVR_WDT)

    #include <Arduino.h>
    #include <avr/wdt.h>

    void BlynkSystemInit(void) __attribute__((naked)) __attribute__((section(".init3")));

    void BlynkSystemInit(void)
    {
        MCUSR = 0;
        wdt_disable();
    }

    void BlynkReset()
    {
        wdt_enable(WDTO_15MS);
        delay(50);
        void(*resetFunc)(void) = 0;
        resetFunc();
        for(;;) {} // To make compiler happy
    }

    size_t BlynkFreeRam()
    {
        extern int __heap_start, *__brkval;
        int v;
        return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && defined(__AVR__)

    #include <Arduino.h>

    void BlynkReset()
    {
        void(*resetFunc)(void) = 0;
        resetFunc();
        for(;;) {}
    }

    size_t BlynkFreeRam()
    {
        extern int __heap_start, *__brkval;
        int v;
        return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && defined(ESP8266)

    #include <Arduino.h>

    size_t BlynkFreeRam()
    {
        return ESP.getFreeHeap();
    }

    void BlynkReset()
    {
        ESP.restart();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)

    #include <Arduino.h>

    size_t BlynkFreeRam()
    {
        return 0;
    }

    void BlynkReset()
    {
        NVIC_SystemReset();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined (ARDUINO_ARCH_ARC32)

    millis_time_t BlynkMillis()
    {
        // TODO: Remove workaround for Intel Curie
        // https://forum.arduino.cc/index.php?topic=391836.0
        noInterrupts();
        uint64_t t = millis();
        interrupts();
        return t;
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(ARDUINO) && (defined(__STM32F1__) || defined(__STM32F3__))

    #include <Arduino.h>
    #include <libmaple/nvic.h>

    void BlynkReset()
    {
        nvic_sys_reset();
        for(;;) {}
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined (PARTICLE) || defined(SPARK)

    #include "application.h"

    void BlynkReset()
    {
        System.reset();
        for(;;) {} // To make compiler happy
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(MBED_LIBRARY_VERSION)

    #include "mbed.h"

    static Timer  blynk_millis_timer;
    static Ticker blynk_waker;

    static
    void blynk_wake() {
        //pc.puts("(...)");
    }

    void BlynkSystemInit(void) __attribute__((naked)) __attribute__((section(".init3")));

    void BlynkSystemInit(void)
    {
        blynk_waker.attach(&blynk_wake, 2.0);
        blynk_millis_timer.start();
    }

    void BlynkDelay(millis_time_t ms)
    {
        wait_ms(ms);
    }

    millis_time_t BlynkMillis()
    {
        return blynk_millis_timer.read_ms();
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET

#elif defined(LINUX) && defined(RASPBERRY)
    #include <stdlib.h>
    #include <wiringPi.h>

    void BlynkSystemInit(void)
    {
        wiringPiSetupGpio();
    }

    void BlynkReset()
    {
        exit(1);
        for(;;) {} // To make compiler happy
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#elif defined(LINUX)

    #define _POSIX_C_SOURCE 200809L
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>

    void BlynkReset()
    {
        exit(1);
        for(;;) {} // To make compiler happy
    }

    void BlynkDelay(millis_time_t ms)
    {
        usleep(ms * 1000);
    }

    millis_time_t BlynkMillis()
    {
        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts );
        return ( ts.tv_sec * 1000 + ts.tv_nsec / 1000000L );
    }

    #define _BLYNK_USE_DEFAULT_FREE_RAM

#else

    #if defined(BLYNK_DEBUG_ALL)
        #warning "Need to implement board-specific utilities"
    #endif

    #define _BLYNK_USE_DEFAULT_FREE_RAM
    #define _BLYNK_USE_DEFAULT_RESET
    #define _BLYNK_USE_DEFAULT_MILLIS
    #define _BLYNK_USE_DEFAULT_DELAY

#endif

#ifdef _BLYNK_USE_DEFAULT_DELAY
    void BlynkDelay(millis_time_t ms)
    {
        return delay(ms);
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_MILLIS
    millis_time_t BlynkMillis()
    {
        return millis();
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_FREE_RAM
    size_t BlynkFreeRam()
    {
        return 0;
    }
#endif

#ifdef _BLYNK_USE_DEFAULT_RESET
    void BlynkReset()
    {
        for(;;) {} // To make compiler happy
    }
#endif

void BlynkFatal()
{
    BlynkDelay(10000L);
    BlynkReset();
}

<|endoftext|>


<commit_before>/*
 * SimpleTimer.cpp
 *
 * SimpleTimer - A timer library for Arduino.
 * Author: mromani@ottotecnica.com
 * Copyright (c) 2010 OTTOTECNICA Italy
 *
 * Callback function parameters added & compiler warnings
 * removed by Bill Knight <billk@rosw.com> 20March2017
 *
 * This library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * 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.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "Blynk/BlynkTimer.h"

// Select time function:
//static inline unsigned long elapsed() { return micros(); }
static inline unsigned long elapsed() { return millis(); }

SimpleTimer::SimpleTimer()
    : numTimers (-1)
{
}

void SimpleTimer::init() {
    unsigned long current_millis = elapsed();

    for (int i = 0; i < MAX_TIMERS; i++) {
        memset(&timer[i], 0, sizeof (timer_t));
        timer[i].prev_millis = current_millis;
    }

    numTimers = 0;
}

void SimpleTimer::run() {
    int i;
    unsigned long current_millis;

    // get current time
    current_millis = elapsed();

    for (i = 0; i < MAX_TIMERS; i++) {

        timer[i].toBeCalled = DEFCALL_DONTRUN;

        // no callback == no timer, i.e. jump over empty slots
        if (timer[i].callback != NULL) {

            // is it time to process this timer ?
            // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592

            if ((current_millis - timer[i].prev_millis) >= timer[i].delay) {

                // update time
                timer[i].prev_millis += timer[i].delay;

                // check if the timer callback has to be executed
                if (timer[i].enabled) {

                    // "run forever" timers must always be executed
                    if (timer[i].maxNumRuns == RUN_FOREVER) {
                        timer[i].toBeCalled = DEFCALL_RUNONLY;
                    }
                    // other timers get executed the specified number of times
                    else if (timer[i].numRuns < timer[i].maxNumRuns) {
                        timer[i].toBeCalled = DEFCALL_RUNONLY;
                        timer[i].numRuns++;

                        // after the last run, delete the timer
                        if (timer[i].numRuns >= timer[i].maxNumRuns) {
                            timer[i].toBeCalled = DEFCALL_RUNANDDEL;
                        }
                    }
                }
            }
        }
    }

    for (i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].toBeCalled == DEFCALL_DONTRUN)
            continue;

        if (timer[i].hasParam)
            (*(timer_callback_p)timer[i].callback)(timer[i].param);
        else
            (*(timer_callback)timer[i].callback)();

        if (timer[i].toBeCalled == DEFCALL_RUNANDDEL)
            deleteTimer(i);
    }
}

// find the first available slot
// return -1 if none found
int SimpleTimer::findFirstFreeSlot() {
    // all slots are used
    if (numTimers >= MAX_TIMERS) {
        return -1;
    }

    // return the first slot with no callback (i.e. free)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback == NULL) {
            return i;
        }
    }

    // no free slots found
    return -1;
}

int SimpleTimer::setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n) {
    int freeTimer;

    if (numTimers < 0) {
        init();
    }

    freeTimer = findFirstFreeSlot();
    if (freeTimer < 0) {
        return -1;
    }

    if (f == NULL) {
        return -1;
    }

    timer[freeTimer].delay = d;
    timer[freeTimer].callback = f;
    timer[freeTimer].param = p;
    timer[freeTimer].hasParam = h;
    timer[freeTimer].maxNumRuns = n;
    timer[freeTimer].enabled = true;
    timer[freeTimer].prev_millis = elapsed();

    numTimers++;

    return freeTimer;
}

int SimpleTimer::setTimer(unsigned long d, timer_callback f, unsigned n) {
  return setupTimer(d, (void *)f, NULL, false, n);
}

int SimpleTimer::setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n) {
  return setupTimer(d, (void *)f, p, true, n);
}

int SimpleTimer::setInterval(unsigned long d, timer_callback f) {
    return setupTimer(d, (void *)f, NULL, false, RUN_FOREVER);
}

int SimpleTimer::setInterval(unsigned long d, timer_callback_p f, void* p) {
  return setupTimer(d, (void *)f, p, true, RUN_FOREVER);
}

int SimpleTimer::setTimeout(unsigned long d, timer_callback f) {
    return setupTimer(d, (void *)f, NULL, false, RUN_ONCE);
}

int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) {
  return setupTimer(d, (void *)f, p, true, RUN_ONCE);
}

bool SimpleTimer::changeInterval(unsigned numTimer, unsigned long d) {
    if (numTimer >= MAX_TIMERS) {
        return false;
    }

    // Updates interval of existing specified timer
    if (timer[numTimer].callback != NULL) {
        timer[numTimer].delay = d;
        timer[numTimer].prev_millis = elapsed();
        return true;
    }
    // false return for non-used numTimer, no callback
    return false;
}

void SimpleTimer::deleteTimer(unsigned timerId) {
    if (timerId >= MAX_TIMERS) {
        return;
    }

    // nothing to delete if no timers are in use
    if (numTimers == 0) {
        return;
    }

    // don't decrease the number of timers if the
    // specified slot is already empty
    if (timer[timerId].callback != NULL) {
        memset(&timer[timerId], 0, sizeof (timer_t));
        timer[timerId].prev_millis = elapsed();

        // update number of timers
        numTimers--;
    }
}

// function contributed by code@rowansimms.com
void SimpleTimer::restartTimer(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].prev_millis = elapsed();
}

bool SimpleTimer::isEnabled(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return false;
    }

    return timer[numTimer].enabled;
}

void SimpleTimer::enable(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = true;
}

void SimpleTimer::disable(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = false;
}

void SimpleTimer::enableAll() {
    // Enable all timers with a callback assigned (used)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback != NULL && numRuns[i] == RUN_FOREVER) {
            timer[i].enabled = true;
        }
    }
}

void SimpleTimer::disableAll() {
    // Disable all timers with a callback assigned (used)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback != NULL && numRuns[i] == RUN_FOREVER) {
            timer[i].enabled = false;
        }
    }
}

void SimpleTimer::toggle(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = !timer[numTimer].enabled;
}

unsigned SimpleTimer::getNumTimers() {
    return numTimers;
}
<commit_msg>Fix timer build<commit_after>/*
 * SimpleTimer.cpp
 *
 * SimpleTimer - A timer library for Arduino.
 * Author: mromani@ottotecnica.com
 * Copyright (c) 2010 OTTOTECNICA Italy
 *
 * Callback function parameters added & compiler warnings
 * removed by Bill Knight <billk@rosw.com> 20March2017
 *
 * This library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * 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.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "Blynk/BlynkTimer.h"
#include <string.h>

// Select time function:
//static inline unsigned long elapsed() { return micros(); }
static inline unsigned long elapsed() { return millis(); }

SimpleTimer::SimpleTimer()
    : numTimers (-1)
{
}

void SimpleTimer::init() {
    unsigned long current_millis = elapsed();

    for (int i = 0; i < MAX_TIMERS; i++) {
        memset(&timer[i], 0, sizeof (timer_t));
        timer[i].prev_millis = current_millis;
    }

    numTimers = 0;
}

void SimpleTimer::run() {
    int i;
    unsigned long current_millis;

    // get current time
    current_millis = elapsed();

    for (i = 0; i < MAX_TIMERS; i++) {

        timer[i].toBeCalled = DEFCALL_DONTRUN;

        // no callback == no timer, i.e. jump over empty slots
        if (timer[i].callback != NULL) {

            // is it time to process this timer ?
            // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592

            if ((current_millis - timer[i].prev_millis) >= timer[i].delay) {

                // update time
                timer[i].prev_millis += timer[i].delay;

                // check if the timer callback has to be executed
                if (timer[i].enabled) {

                    // "run forever" timers must always be executed
                    if (timer[i].maxNumRuns == RUN_FOREVER) {
                        timer[i].toBeCalled = DEFCALL_RUNONLY;
                    }
                    // other timers get executed the specified number of times
                    else if (timer[i].numRuns < timer[i].maxNumRuns) {
                        timer[i].toBeCalled = DEFCALL_RUNONLY;
                        timer[i].numRuns++;

                        // after the last run, delete the timer
                        if (timer[i].numRuns >= timer[i].maxNumRuns) {
                            timer[i].toBeCalled = DEFCALL_RUNANDDEL;
                        }
                    }
                }
            }
        }
    }

    for (i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].toBeCalled == DEFCALL_DONTRUN)
            continue;

        if (timer[i].hasParam)
            (*(timer_callback_p)timer[i].callback)(timer[i].param);
        else
            (*(timer_callback)timer[i].callback)();

        if (timer[i].toBeCalled == DEFCALL_RUNANDDEL)
            deleteTimer(i);
    }
}

// find the first available slot
// return -1 if none found
int SimpleTimer::findFirstFreeSlot() {
    // all slots are used
    if (numTimers >= MAX_TIMERS) {
        return -1;
    }

    // return the first slot with no callback (i.e. free)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback == NULL) {
            return i;
        }
    }

    // no free slots found
    return -1;
}

int SimpleTimer::setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n) {
    int freeTimer;

    if (numTimers < 0) {
        init();
    }

    freeTimer = findFirstFreeSlot();
    if (freeTimer < 0) {
        return -1;
    }

    if (f == NULL) {
        return -1;
    }

    timer[freeTimer].delay = d;
    timer[freeTimer].callback = f;
    timer[freeTimer].param = p;
    timer[freeTimer].hasParam = h;
    timer[freeTimer].maxNumRuns = n;
    timer[freeTimer].enabled = true;
    timer[freeTimer].prev_millis = elapsed();

    numTimers++;

    return freeTimer;
}

int SimpleTimer::setTimer(unsigned long d, timer_callback f, unsigned n) {
  return setupTimer(d, (void *)f, NULL, false, n);
}

int SimpleTimer::setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n) {
  return setupTimer(d, (void *)f, p, true, n);
}

int SimpleTimer::setInterval(unsigned long d, timer_callback f) {
    return setupTimer(d, (void *)f, NULL, false, RUN_FOREVER);
}

int SimpleTimer::setInterval(unsigned long d, timer_callback_p f, void* p) {
  return setupTimer(d, (void *)f, p, true, RUN_FOREVER);
}

int SimpleTimer::setTimeout(unsigned long d, timer_callback f) {
    return setupTimer(d, (void *)f, NULL, false, RUN_ONCE);
}

int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) {
  return setupTimer(d, (void *)f, p, true, RUN_ONCE);
}

bool SimpleTimer::changeInterval(unsigned numTimer, unsigned long d) {
    if (numTimer >= MAX_TIMERS) {
        return false;
    }

    // Updates interval of existing specified timer
    if (timer[numTimer].callback != NULL) {
        timer[numTimer].delay = d;
        timer[numTimer].prev_millis = elapsed();
        return true;
    }
    // false return for non-used numTimer, no callback
    return false;
}

void SimpleTimer::deleteTimer(unsigned timerId) {
    if (timerId >= MAX_TIMERS) {
        return;
    }

    // nothing to delete if no timers are in use
    if (numTimers == 0) {
        return;
    }

    // don't decrease the number of timers if the
    // specified slot is already empty
    if (timer[timerId].callback != NULL) {
        memset(&timer[timerId], 0, sizeof (timer_t));
        timer[timerId].prev_millis = elapsed();

        // update number of timers
        numTimers--;
    }
}

// function contributed by code@rowansimms.com
void SimpleTimer::restartTimer(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].prev_millis = elapsed();
}

bool SimpleTimer::isEnabled(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return false;
    }

    return timer[numTimer].enabled;
}

void SimpleTimer::enable(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = true;
}

void SimpleTimer::disable(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = false;
}

void SimpleTimer::enableAll() {
    // Enable all timers with a callback assigned (used)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
            timer[i].enabled = true;
        }
    }
}

void SimpleTimer::disableAll() {
    // Disable all timers with a callback assigned (used)
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
            timer[i].enabled = false;
        }
    }
}

void SimpleTimer::toggle(unsigned numTimer) {
    if (numTimer >= MAX_TIMERS) {
        return;
    }

    timer[numTimer].enabled = !timer[numTimer].enabled;
}

unsigned SimpleTimer::getNumTimers() {
    return numTimers;
}
<|endoftext|>


<commit_before>#include "dsa_common.h"

#include "broker.h"

//#include "boost/asio/strand.hpp"

#include "config/broker_config.h"
#include "config/module_loader.h"
#include "module/logger.h"
#include "module/security_manager.h"
#include "network/tcp/tcp_server.h"
#include "network/ws/ws_callback.h"
#include "node/broker_root.h"
#include "node/downstream/downstream_root.h"
#include "remote_node/broker_session_manager.h"
#include "remote_node/remote_root_node.h"
#include "responder/node_state_manager.h"
#include "util/app.h"
#include "web_server/web_server.h"

namespace dsa {
DsBroker::DsBroker(ref_<BrokerConfig>&& config, ModuleLoader& modules,
                   const shared_ptr_<App>& app)
    : _config(std::move(config)), _app(app) {
  init(modules);
}
DsBroker::~DsBroker() {}

void DsBroker::init(ModuleLoader& modules) {
  if (_app == nullptr) {
    // init app
    size_t thread =
        static_cast<size_t>(_config->thread().get_value().get_int());
    if (thread < 1 || thread > 16) {
      thread = 1;
    }
    _app.reset(new App(thread));
  }

  server_host = _config->host().get_value().get_string();
  tcp_server_port =
      static_cast<uint16_t>(_config->port().get_value().get_int());
  tcp_secure_port =
      static_cast<uint16_t>(_config->secure_port().get_value().get_int());
  uint16_t http_port =
      static_cast<uint16_t>(_config->http_port().get_value().get_int());
  uint16_t https_port =
      static_cast<uint16_t>(_config->https_port().get_value().get_int());

  strand.reset(new EditableStrand(
      _app->new_strand(), std::unique_ptr<ECDH>(ECDH::from_file(".key"))));

  // init logger
  std::unique_ptr<Logger> logger = modules.new_logger(*_app, strand);
  logger->level = Logger::parse(_config->log_level().get_value().to_string());
  strand->set_logger(std::move(logger));

  // init security manager
  strand->set_security_manager(modules.new_security_manager(*_app, strand));

  auto broker_root = make_ref_<BrokerRoot>(strand->get_ref(), get_ref());
  // init responder
  strand->set_stream_acceptor(
      make_ref_<NodeStateManager>(*strand, broker_root->get_ref()));

  // init session manager
  strand->set_session_manager(
      make_ref_<BrokerSessionManager>(strand, broker_root->_downstream_root));
}
void DsBroker::destroy_impl() {
  if (_tcp_server != nullptr) {
    _tcp_server->destroy();
    _tcp_server.reset();
  }
  _config.reset();

  WrapperStrand::destroy_impl();
  _app->close();
}
void DsBroker::run() {

  // start web_server
  auto web_server = std::make_shared<WebServer>(*_app);
  uint16_t http_port =
      static_cast<uint16_t>(_config->http_port().get_value().get_int());
  web_server->listen(http_port);
  web_server->start();
  WebServer::WsCallback root_cb = [this](
      WebServer& web_server,
      boost::asio::ip::tcp::socket&& socket,
      boost::beast::http::request<boost::beast::http::string_body> req)
  {
    LinkStrandRef link_strand(strand);
    DsaWsCallback dsa_ws_callback(link_strand);
    dsa_ws_callback(web_server.io_service(), std::move(socket), std::move(req));
  };

  // TOOD - websocket callback setup
  web_server->add_ws_handler("/", std::move(root_cb));

  // start tcp server
  strand->dispatch([this]() {
    if (tcp_server_port > 0) {
      _tcp_server = make_shared_<TcpServer>(*this);
      _tcp_server->start();
      LOG_SYSTEM(strand->logger(), LOG << "DsBroker started");
    }
  });
  _app->wait();
  destroy();
}
}
<commit_msg>disable the webserver for now<commit_after>#include "dsa_common.h"

#include "broker.h"

//#include "boost/asio/strand.hpp"

#include "config/broker_config.h"
#include "config/module_loader.h"
#include "module/logger.h"
#include "module/security_manager.h"
#include "network/tcp/tcp_server.h"
#include "network/ws/ws_callback.h"
#include "node/broker_root.h"
#include "node/downstream/downstream_root.h"
#include "remote_node/broker_session_manager.h"
#include "remote_node/remote_root_node.h"
#include "responder/node_state_manager.h"
#include "util/app.h"
#include "web_server/web_server.h"

namespace dsa {
DsBroker::DsBroker(ref_<BrokerConfig>&& config, ModuleLoader& modules,
                   const shared_ptr_<App>& app)
    : _config(std::move(config)), _app(app) {
  init(modules);
}
DsBroker::~DsBroker() {}

void DsBroker::init(ModuleLoader& modules) {
  if (_app == nullptr) {
    // init app
    size_t thread =
        static_cast<size_t>(_config->thread().get_value().get_int());
    if (thread < 1 || thread > 16) {
      thread = 1;
    }
    _app.reset(new App(thread));
  }

  server_host = _config->host().get_value().get_string();
  tcp_server_port =
      static_cast<uint16_t>(_config->port().get_value().get_int());
  tcp_secure_port =
      static_cast<uint16_t>(_config->secure_port().get_value().get_int());
  uint16_t http_port =
      static_cast<uint16_t>(_config->http_port().get_value().get_int());
  uint16_t https_port =
      static_cast<uint16_t>(_config->https_port().get_value().get_int());

  strand.reset(new EditableStrand(
      _app->new_strand(), std::unique_ptr<ECDH>(ECDH::from_file(".key"))));

  // init logger
  std::unique_ptr<Logger> logger = modules.new_logger(*_app, strand);
  logger->level = Logger::parse(_config->log_level().get_value().to_string());
  strand->set_logger(std::move(logger));

  // init security manager
  strand->set_security_manager(modules.new_security_manager(*_app, strand));

  auto broker_root = make_ref_<BrokerRoot>(strand->get_ref(), get_ref());
  // init responder
  strand->set_stream_acceptor(
      make_ref_<NodeStateManager>(*strand, broker_root->get_ref()));

  // init session manager
  strand->set_session_manager(
      make_ref_<BrokerSessionManager>(strand, broker_root->_downstream_root));
}
void DsBroker::destroy_impl() {
  if (_tcp_server != nullptr) {
    _tcp_server->destroy();
    _tcp_server.reset();
  }
  _config.reset();

  WrapperStrand::destroy_impl();
  _app->close();
}
void DsBroker::run() {

#if 0
  // start web_server
  auto web_server = std::make_shared<WebServer>(*_app);
  uint16_t http_port =
      static_cast<uint16_t>(_config->http_port().get_value().get_int());
  web_server->listen(http_port);
  web_server->start();
  WebServer::WsCallback root_cb = [this](
      WebServer& web_server,
      boost::asio::ip::tcp::socket&& socket,
      boost::beast::http::request<boost::beast::http::string_body> req)
  {
    LinkStrandRef link_strand(strand);
    DsaWsCallback dsa_ws_callback(link_strand);
    dsa_ws_callback(web_server.io_service(), std::move(socket), std::move(req));
  };

  // TODO - websocket callback setup
  web_server->add_ws_handler("/", std::move(root_cb));
#endif

  // start tcp server
  strand->dispatch([this]() {
    if (tcp_server_port > 0) {
      _tcp_server = make_shared_<TcpServer>(*this);
      _tcp_server->start();
      LOG_SYSTEM(strand->logger(), LOG << "DsBroker started");
    }
  });
  _app->wait();
  destroy();
}
}
<|endoftext|>


<commit_before>//
//  dfa_single_regex.cpp
//  Parse
//
//  Created by Andrew Hunter on 28/04/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include <string>
#include <sstream>

#include "dfa_single_regex.h"

#include "Dfa/lexer.h"

using namespace std;
using namespace dfa;

void test_dfa_single_regex::test(std::string name, std::string regex, std::string accepting, std::string rejecting) {
    // Create a lexer that accepts the regular expression
    lexer myLexer;
    myLexer.add_symbol(regex, 1);

    lexer myCompactLexer;
    myCompactLexer.add_symbol(regex, 1);

    // Compile it
    myLexer.compile(false);
    myCompactLexer.compile(true);

    // Try the accepting phrase
    stringstream acceptIn(accepting);
    lexeme_stream* stream = myLexer.create_stream_from(acceptIn);

    // Get the first lexeme
    lexeme* first;
    (*stream) >> first;
    delete stream;

    // Try again with the compact lexer
    stringstream acceptCompactIn(accepting);
    stream = myCompactLexer.create_stream_from(acceptCompactIn);

    lexeme* firstCompact;
    (*stream) >> firstCompact;
    delete stream;

    // Try the rejecting phrase
    stringstream rejectIn(rejecting);
    stream = myLexer.create_stream_from(rejectIn);

    lexeme* fail;
    (*stream) >> fail;

    delete stream;

    // first lexeme should be an accepting lexeme, second should be a rejection
    if (first != NULL && fail != NULL && first->matched() == 1 && first->content<char>() == accepting
        && firstCompact != NULL && firstCompact->matched() == 1 && firstCompact->content<char>() == accepting
        && fail != NULL && fail->matched() == -1 && fail->content().size() == 1) {
        report(name, true);
    } else {
        // Break things down if we get a failure
        report(name + "-accept", first != NULL && first->matched() == 1);
        report(name + "-content", first != NULL && first->content<char>() == accepting);

        report(name + "-compact-accept", firstCompact != NULL && firstCompact->matched() == 1);
        report(name + "-compact-content", firstCompact != NULL && firstCompact->content<char>() == accepting);

        report(name + "-reject", fail != NULL && fail->matched() == -1);
        report(name + "-rejectone", fail != NULL && fail->content().size() == 1);
    }

    delete first;
    delete firstCompact;
    delete fail;
}

void test_dfa_single_regex::run_tests() {
    test("basic", "a", "a", "b");
    test("sayaaaa", "a*", "aaaaa", "b");
    test("ababab", "(ab)+", "ababab", "aaaaaa");

    test("a-or-b1", "a|b", "a", "c");
    test("a-or-b2", "a|b", "b", "c");
    test("a-or-b3", "a+|b+", "aaaaa", "c");
    test("a-or-b4", "a+|b+", "bbbbb", "c");
    test("a-or-b5", "a*|b*", "aaaaa", "c");
    test("a-or-b6", "a*|b*", "bbbbb", "c");
    test("a-or-b7", "(a*)|(b*)", "bbbbb", "c");
    test("a-or-b8", "(a+)|(b+)", "bbbbb", "c");

    test("ab-or-cd1", "ab|cd", "ab", "a");
    test("ab-or-cd2", "ab|cd", "cd", "a");
    test("ab-or-cd3", "(ab)+|(cd)+", "ababab", "a");
    test("ab-or-cd4", "(ab)+|(cd)+", "cdcdcd", "c");
    test("ab-or-cd5", "(ab)+|((cd)+)", "cdcdcd", "c");

    test("ab-or-cd-or-ef1", "ab|cd|ef", "ab", "af");
    test("ab-or-cd-or-ef2", "ab|cd|ef", "cd", "c");
    test("ab-or-cd-or-ef3", "ab|cd|ef", "ef", "d");

    test("a-or-b-c1", "(a|b?)c", "ac", "a");
    test("a-or-b-c2", "(a|b?)c", "bc", "b");
    test("a-or-b-c3", "(a|b?)c", "c", "b");

    test("escape1", "\\a", "\a", "b");
    test("escape2", "\\e", "\e", "b");
    test("escape3", "\\n", "\n", "b");
    test("escape4", "\\r", "\r", "b");
    test("escape5", "\\f", "\f", "b");
    test("escape6", "\\t", "\t", "b");
    test("escape7", "\\101", "A", "b");
    test("escape8", "\\x41", "A", "b");
    test("escape9", "\\u0041", "A", "b");
    test("escape10", "\\o000101", "A", "b");

    test("range1", "[a-z]", "a", "0");
    test("range2", "[a-z]", "z", "0");
    test("range3", "[^a-z]", "0", "a");
    test("range4", "[abc]+", "abc", "d");
    test("range5", "[a-zA-Z]+", "azAZ", "0");
    test("range5-withor", "([a-z]|[A-Z])+", "azAZ", "0");
    test("range6", "[a-c]+", "abc", "d");
    test("range7", "[azAZ]+", "azAZ", "0");
    test("range8", "[azAZ]+", "a", "0");
    test("range9", "[azAZ]+", "z", "0");
    test("range10", "[azAZ]+", "A", "0");
    test("range11", "[azAZ]+", "Z", "0");
    test("range12", "([a-f][c-h])+", "ccah", "ha");

    test("bootstrap-identifier1", "[A-Za-z\\-][A-Za-z\\-0-9]*", "some-identifier", "0");
    test("bootstrap-identifier2", "[A-Za-z\\-][A-Za-z\\-0-9]*", "language", "0");
}
<commit_msg>And some tests using the | operator to see if we get a rejection that way; doesn't look like it. Need some 'can we distinguish things' tests now :-/<commit_after>//
//  dfa_single_regex.cpp
//  Parse
//
//  Created by Andrew Hunter on 28/04/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include <string>
#include <sstream>

#include "dfa_single_regex.h"

#include "Dfa/lexer.h"

using namespace std;
using namespace dfa;

void test_dfa_single_regex::test(std::string name, std::string regex, std::string accepting, std::string rejecting) {
    // Create a lexer that accepts the regular expression
    lexer myLexer;
    myLexer.add_symbol(regex, 1);

    lexer myCompactLexer;
    myCompactLexer.add_symbol(regex, 1);

    // Compile it
    myLexer.compile(false);
    myCompactLexer.compile(true);

    // Try the accepting phrase
    stringstream acceptIn(accepting);
    lexeme_stream* stream = myLexer.create_stream_from(acceptIn);

    // Get the first lexeme
    lexeme* first;
    (*stream) >> first;
    delete stream;

    // Try again with the compact lexer
    stringstream acceptCompactIn(accepting);
    stream = myCompactLexer.create_stream_from(acceptCompactIn);

    lexeme* firstCompact;
    (*stream) >> firstCompact;
    delete stream;

    // Try the rejecting phrase
    stringstream rejectIn(rejecting);
    stream = myLexer.create_stream_from(rejectIn);

    lexeme* fail;
    (*stream) >> fail;

    delete stream;

    // first lexeme should be an accepting lexeme, second should be a rejection
    if (first != NULL && fail != NULL && first->matched() == 1 && first->content<char>() == accepting
        && firstCompact != NULL && firstCompact->matched() == 1 && firstCompact->content<char>() == accepting
        && fail != NULL && fail->matched() == -1 && fail->content().size() == 1) {
        report(name, true);
    } else {
        // Break things down if we get a failure
        report(name + "-accept", first != NULL && first->matched() == 1);
        report(name + "-content", first != NULL && first->content<char>() == accepting);

        report(name + "-compact-accept", firstCompact != NULL && firstCompact->matched() == 1);
        report(name + "-compact-content", firstCompact != NULL && firstCompact->content<char>() == accepting);

        report(name + "-reject", fail != NULL && fail->matched() == -1);
        report(name + "-rejectone", fail != NULL && fail->content().size() == 1);
    }

    delete first;
    delete firstCompact;
    delete fail;
}

void test_dfa_single_regex::run_tests() {
    test("basic", "a", "a", "b");
    test("sayaaaa", "a*", "aaaaa", "b");
    test("ababab", "(ab)+", "ababab", "aaaaaa");

    test("a-or-b1", "a|b", "a", "c");
    test("a-or-b2", "a|b", "b", "c");
    test("a-or-b3", "a+|b+", "aaaaa", "c");
    test("a-or-b4", "a+|b+", "bbbbb", "c");
    test("a-or-b5", "a*|b*", "aaaaa", "c");
    test("a-or-b6", "a*|b*", "bbbbb", "c");
    test("a-or-b7", "(a*)|(b*)", "bbbbb", "c");
    test("a-or-b8", "(a+)|(b+)", "bbbbb", "c");

    test("ab-or-cd1", "ab|cd", "ab", "a");
    test("ab-or-cd2", "ab|cd", "cd", "a");
    test("ab-or-cd3", "(ab)+|(cd)+", "ababab", "a");
    test("ab-or-cd4", "(ab)+|(cd)+", "cdcdcd", "c");
    test("ab-or-cd5", "(ab)+|((cd)+)", "cdcdcd", "c");

    test("ab-or-cd-or-ef1", "ab|cd|ef", "ab", "af");
    test("ab-or-cd-or-ef2", "ab|cd|ef", "cd", "c");
    test("ab-or-cd-or-ef3", "ab|cd|ef", "ef", "d");

    test("a-or-b-c1", "(a|b?)c", "ac", "a");
    test("a-or-b-c2", "(a|b?)c", "bc", "b");
    test("a-or-b-c3", "(a|b?)c", "c", "b");

    test("escape1", "\\a", "\a", "b");
    test("escape2", "\\e", "\e", "b");
    test("escape3", "\\n", "\n", "b");
    test("escape4", "\\r", "\r", "b");
    test("escape5", "\\f", "\f", "b");
    test("escape6", "\\t", "\t", "b");
    test("escape7", "\\101", "A", "b");
    test("escape8", "\\x41", "A", "b");
    test("escape9", "\\u0041", "A", "b");
    test("escape10", "\\o000101", "A", "b");

    test("range1", "[a-z]", "a", "0");
    test("range2", "[a-z]", "z", "0");
    test("range3", "[^a-z]", "0", "a");
    test("range4", "[abc]+", "abc", "d");
    test("range5", "[a-zA-Z]+", "azAZ", "0");
    test("range5-withor", "([a-z]|[A-Z])+", "azAZ", "0");
    test("range6", "[a-c]+", "abc", "d");
    test("range7", "[azAZ]+", "azAZ", "0");
    test("range8", "[azAZ]+", "a", "0");
    test("range9", "[azAZ]+", "z", "0");
    test("range10", "[azAZ]+", "A", "0");
    test("range11", "[azAZ]+", "Z", "0");
    test("range12", "([a-f][c-h])+", "ccah", "ha");

    test("bootstrap-identifier1", "[A-Za-z\\-][A-Za-z\\-0-9]*", "some-identifier", "0");
    test("bootstrap-identifier2", "[A-Za-z\\-][A-Za-z\\-0-9]*", "language", "0");
    test("bootstrap-identifier3", "([A-Za-z\\-][A-Za-z\\-0-9]*)|(language)", "language", "0");
    test("bootstrap-identifier4", "([A-Za-z\\-][A-Za-z\\-0-9]*)|(language)", "some-identifier", "0");
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/utp_stream.hpp"
#include "libtorrent/udp_socket.hpp"

namespace libtorrent
{

	utp_socket_manager::utp_socket_manager(udp_socket& s, incoming_utp_fun cb
		, void* userdata)
		: m_sock(s)
		, m_cb(cb)
		, m_userdata(userdata)
	{}

	void utp_socket_manager::tick()
	{
		for (socket_map::iterator i = m_utp_sockets.begin()
			, end(m_utp_sockets.end()); i != end; ++i)
		{
			i->second->tick();
		}
	}

	bool utp_socket_manager::incoming_packet(char const* p, int size)
	{
		if (size < sizeof(utp_header)) return false;

		utp_header const* ph = (utp_header*)p;

		if (ph->ver != 1) return false;

		// parse out connection ID and look for existing
		// connections. If found, forward to the utp_stream.
		boost::uint16_t id = ph->connection_id;
		socket_map_t::iterator i = m_utp_sockets.find(id);

		// if not found, see if it's a SYN packet, if it is,
		// create a new utp_stream
		if (i == m_utp_sockets.end() && ph->type == ST_SYN)
		{
			boost::uint16_t id = rand();
			boost::shared_ptr<utp_stream> c = new utp_stream(*this, id);

			TORRENT_ASSERT(m_utp_sockets.find(id) == m_utp_sockets.end());
			i = m_utp_sockets.insert(std::make_pair(id, c.get()));
			m_cb(m_userdata, c);
		}

		if (i != m_utp_sockets.end())
			return i->second->incoming_packet(p, size);

		return false;
	}

	void utp_socket_manager::remove_socket(boost::uint16_t id)
	{
		socket_map_t::iterator i = m_utp_sockets.find(id);
		if (i == m_utp_sockets.end()) return;
		m_utp_sockets.erase(i);
	}

	void utp_socket_manager::add_socket(boost::uint16_t id, utp_stream* s)
	{
	}
}

<commit_msg>Fixed typo in utp_socket_manager.cpp.<commit_after>/*

Copyright (c) 2009, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/utp_stream.hpp"
#include "libtorrent/udp_socket.hpp"

namespace libtorrent
{

	utp_socket_manager::utp_socket_manager(udp_socket& s, incoming_utp_fun cb
		, void* userdata)
		: m_sock(s)
		, m_cb(cb)
		, m_userdata(userdata)
	{}

	void utp_socket_manager::tick()
	{
		for (socket_map_t::iterator i = m_utp_sockets.begin()
			, end(m_utp_sockets.end()); i != end; ++i)
		{
			i->second->tick();
		}
	}

	bool utp_socket_manager::incoming_packet(char const* p, int size)
	{
		if (size < sizeof(utp_header)) return false;

		utp_header const* ph = (utp_header*)p;

		if (ph->ver != 1) return false;

		// parse out connection ID and look for existing
		// connections. If found, forward to the utp_stream.
		boost::uint16_t id = ph->connection_id;
		socket_map_t::iterator i = m_utp_sockets.find(id);

		// if not found, see if it's a SYN packet, if it is,
		// create a new utp_stream
		if (i == m_utp_sockets.end() && ph->type == ST_SYN)
		{
			boost::uint16_t id = rand();
			boost::shared_ptr<utp_stream> c = new utp_stream(*this, id);

			TORRENT_ASSERT(m_utp_sockets.find(id) == m_utp_sockets.end());
			i = m_utp_sockets.insert(std::make_pair(id, c.get()));
			m_cb(m_userdata, c);
		}

		if (i != m_utp_sockets.end())
			return i->second->incoming_packet(p, size);

		return false;
	}

	void utp_socket_manager::remove_socket(boost::uint16_t id)
	{
		socket_map_t::iterator i = m_utp_sockets.find(id);
		if (i == m_utp_sockets.end()) return;
		m_utp_sockets.erase(i);
	}

	void utp_socket_manager::add_socket(boost::uint16_t id, utp_stream* s)
	{
	}
}

<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//
#include "VDPAUDecoder.h"
#include "VDPAUHelper.h"

#include "../base/Exception.h"

#include <iostream>

using namespace std;

namespace avg {

VDPAUDecoder::VDPAUDecoder()
    : m_VDPDecoder(VDP_INVALID_HANDLE),
      m_VDPMixer(VDP_INVALID_HANDLE),
      m_PixFmt(PIX_FMT_NONE),
      m_Size(-1,-1)
{
}

VDPAUDecoder::~VDPAUDecoder()
{
    if (m_VDPMixer != VDP_INVALID_HANDLE) {
        vdp_video_mixer_destroy(m_VDPMixer);
    }
    if (m_VDPDecoder != VDP_INVALID_HANDLE) {
        vdp_decoder_destroy(m_VDPDecoder);
    }
    for (unsigned i = 0; i < m_RenderStates.size(); i++) {
        vdp_video_surface_destroy(m_RenderStates[i]->surface);
        delete m_RenderStates[i];
    }
}

AVCodec* VDPAUDecoder::openCodec(AVCodecContext* pContext)
{
    getVDPAUDevice();

    AVCodec* pCodec = 0;
    switch (pContext->codec_id) {
        case CODEC_ID_MPEG1VIDEO:
            pCodec = avcodec_find_decoder_by_name("mpeg1video_vdpau");
            pCodec->id = CODEC_ID_MPEG1VIDEO;
            break;
        case CODEC_ID_MPEG2VIDEO:
            pCodec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
            break;
        case CODEC_ID_H264:
            pCodec = avcodec_find_decoder_by_name("h264_vdpau");
            break;
        case CODEC_ID_WMV3:
            pCodec = avcodec_find_decoder_by_name("wmv3_vdpau");
            break;
        case CODEC_ID_VC1:
            pCodec = avcodec_find_decoder_by_name("vc1_vdpau");
            break;
        default:
            pCodec = 0;
    }
    if (!pCodec || !getVDPAUDevice()) {
        pCodec = avcodec_find_decoder(pContext->codec_id);
    } else {
        pContext->get_buffer = VDPAUDecoder::getBuffer;
        pContext->release_buffer = VDPAUDecoder::releaseBuffer;
        pContext->draw_horiz_band = VDPAUDecoder::drawHorizBand;
        pContext->get_format = VDPAUDecoder::getFormat;
        pContext->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
        m_Size = IntPoint(pContext->width, pContext->height);
    }
    return pCodec;
}

bool VDPAUDecoder::isAvailable()
{
    return getVDPAUDevice() != 0;
}

int VDPAUDecoder::getBuffer(AVCodecContext* pContext, AVFrame* pFrame)
{
    VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
    return pVDPAUDecoder->getBufferInternal(pContext, pFrame);
}

// does not release the render structure, that will be unlocked after getting data
void VDPAUDecoder::releaseBuffer(struct AVCodecContext* pContext, AVFrame* pFrame)
{
    pFrame->data[0] = 0;
}

// main rendering routine
void VDPAUDecoder::drawHorizBand(struct AVCodecContext* pContext, const AVFrame* src,
        int offset[4], int y, int type, int height)
{
    VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
    pVDPAUDecoder->render(pContext, src);
}

::PixelFormat VDPAUDecoder::getFormat(AVCodecContext* pContext, const ::PixelFormat* pFmt)
{
    switch (pContext->codec_id) {
        case CODEC_ID_H264:
            return PIX_FMT_VDPAU_H264;
        case CODEC_ID_MPEG1VIDEO:
            return PIX_FMT_VDPAU_MPEG1;
        case CODEC_ID_MPEG2VIDEO:
            return PIX_FMT_VDPAU_MPEG2;
        case CODEC_ID_WMV3:
            return PIX_FMT_VDPAU_WMV3;
        case CODEC_ID_VC1:
            return PIX_FMT_VDPAU_VC1;
        default:
            return pFmt[0];
    }
}

vdpau_render_state* VDPAUDecoder::getFreeRenderState()
{
    for (unsigned i = 0; i < m_RenderStates.size(); i++) {
        vdpau_render_state* pRenderState = m_RenderStates[i];
        if (!(pRenderState->state & FF_VDPAU_STATE_USED_FOR_REFERENCE)) {
            return m_RenderStates[i];
        }
    }

    // No free surfaces available -> create new surface
    vdpau_render_state* pRenderState = new vdpau_render_state;
    memset(pRenderState, 0, sizeof(vdpau_render_state));
    pRenderState->surface = VDP_INVALID_HANDLE;
    VdpStatus status = vdp_video_surface_create(getVDPAUDevice(), VDP_CHROMA_TYPE_420,
            m_Size.x, m_Size.y, &pRenderState->surface);
    AVG_ASSERT(status == VDP_STATUS_OK);

    return pRenderState;
}

int VDPAUDecoder::getBufferInternal(AVCodecContext* pContext, AVFrame* pFrame)
{
    vdpau_render_state* pRenderState = getFreeRenderState();
    pFrame->data[0] = (uint8_t*)pRenderState;
    pFrame->type = FF_BUFFER_TYPE_USER;

    pRenderState->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE;
    return 0;
}

void VDPAUDecoder::render(AVCodecContext* pContext, const AVFrame* pFrame)
{
    vdpau_render_state* pRenderState = (vdpau_render_state*)pFrame->data[0];

    if (m_VDPDecoder == VDP_INVALID_HANDLE) {
        setupDecoder(pContext);
    }

    VdpStatus status = vdp_decoder_render(m_VDPDecoder, pRenderState->surface,
            (VdpPictureInfo const*)&(pRenderState->info),
            pRenderState->bitstream_buffers_used, pRenderState->bitstream_buffers);
    AVG_ASSERT(status == VDP_STATUS_OK);
}

void VDPAUDecoder::setupDecoder(AVCodecContext* pContext)
{
    VdpStatus status;

    // Create new decoder and mixer.
    VdpDecoderProfile profile = 0;
    switch (pContext->pix_fmt) {
        case PIX_FMT_VDPAU_MPEG1:
            profile = VDP_DECODER_PROFILE_MPEG1;
            break;
        case PIX_FMT_VDPAU_MPEG2:
            profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
            break;
        case PIX_FMT_VDPAU_H264:
            profile = VDP_DECODER_PROFILE_H264_HIGH;
            break;
        case PIX_FMT_VDPAU_WMV3:
            profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
            break;
        case PIX_FMT_VDPAU_VC1:
            profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
            break;
        default:
            AVG_ASSERT(false);
    }
    status = vdp_decoder_create(getVDPAUDevice(), profile, m_Size.x, m_Size.y, 16,
            &m_VDPDecoder);
    AVG_ASSERT(status == VDP_STATUS_OK);

    m_PixFmt = pContext->pix_fmt;

    VdpVideoMixerFeature features[] = {
        VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL,
        VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL,
    };
    VdpVideoMixerParameter params[] = {
        VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
        VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
        VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE,
        VDP_VIDEO_MIXER_PARAMETER_LAYERS
    };
    VdpChromaType chroma = VDP_CHROMA_TYPE_420;
    int  numLayers = 0;
    void const* paramValues [] = { &m_Size.x, &m_Size.y, &chroma, &numLayers };

    status = vdp_video_mixer_create(getVDPAUDevice(), 2, features, 4, params,
            paramValues, &m_VDPMixer);
    AVG_ASSERT(status == VDP_STATUS_OK);

}

}

<commit_msg>Disable VDPAU if using old ffmpeg.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//
#include "VDPAUDecoder.h"
#include "VDPAUHelper.h"

#include "../base/Exception.h"

#include <iostream>

using namespace std;

namespace avg {

VDPAUDecoder::VDPAUDecoder()
    : m_VDPDecoder(VDP_INVALID_HANDLE),
      m_VDPMixer(VDP_INVALID_HANDLE),
      m_PixFmt(PIX_FMT_NONE),
      m_Size(-1,-1)
{
}

VDPAUDecoder::~VDPAUDecoder()
{
    if (m_VDPMixer != VDP_INVALID_HANDLE) {
        vdp_video_mixer_destroy(m_VDPMixer);
    }
    if (m_VDPDecoder != VDP_INVALID_HANDLE) {
        vdp_decoder_destroy(m_VDPDecoder);
    }
    for (unsigned i = 0; i < m_RenderStates.size(); i++) {
        vdp_video_surface_destroy(m_RenderStates[i]->surface);
        delete m_RenderStates[i];
    }
}

AVCodec* VDPAUDecoder::openCodec(AVCodecContext* pContext)
{
    getVDPAUDevice();

    AVCodec* pCodec = 0;
    switch (pContext->codec_id) {
        case CODEC_ID_MPEG1VIDEO:
            pCodec = avcodec_find_decoder_by_name("mpeg1video_vdpau");
            pCodec->id = CODEC_ID_MPEG1VIDEO;
            break;
        case CODEC_ID_MPEG2VIDEO:
            pCodec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
            break;
        case CODEC_ID_H264:
            pCodec = avcodec_find_decoder_by_name("h264_vdpau");
            break;
        case CODEC_ID_WMV3:
            pCodec = avcodec_find_decoder_by_name("wmv3_vdpau");
            break;
        case CODEC_ID_VC1:
            pCodec = avcodec_find_decoder_by_name("vc1_vdpau");
            break;
        default:
            pCodec = 0;
    }
    if (!pCodec || !getVDPAUDevice()) {
        pCodec = avcodec_find_decoder(pContext->codec_id);
    } else {
        pContext->get_buffer = VDPAUDecoder::getBuffer;
        pContext->release_buffer = VDPAUDecoder::releaseBuffer;
        pContext->draw_horiz_band = VDPAUDecoder::drawHorizBand;
        pContext->get_format = VDPAUDecoder::getFormat;
        pContext->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
        m_Size = IntPoint(pContext->width, pContext->height);
    }
    return pCodec;
}

bool VDPAUDecoder::isAvailable()
{
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 34, 0)
    return getVDPAUDevice() != 0;
#else
    return false;
#endif
}

int VDPAUDecoder::getBuffer(AVCodecContext* pContext, AVFrame* pFrame)
{
    VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
    return pVDPAUDecoder->getBufferInternal(pContext, pFrame);
}

// does not release the render structure, that will be unlocked after getting data
void VDPAUDecoder::releaseBuffer(struct AVCodecContext* pContext, AVFrame* pFrame)
{
    pFrame->data[0] = 0;
}

// main rendering routine
void VDPAUDecoder::drawHorizBand(struct AVCodecContext* pContext, const AVFrame* src,
        int offset[4], int y, int type, int height)
{
    VDPAUDecoder* pVDPAUDecoder = (VDPAUDecoder*)pContext->opaque;
    pVDPAUDecoder->render(pContext, src);
}

::PixelFormat VDPAUDecoder::getFormat(AVCodecContext* pContext, const ::PixelFormat* pFmt)
{
    switch (pContext->codec_id) {
        case CODEC_ID_H264:
            return PIX_FMT_VDPAU_H264;
        case CODEC_ID_MPEG1VIDEO:
            return PIX_FMT_VDPAU_MPEG1;
        case CODEC_ID_MPEG2VIDEO:
            return PIX_FMT_VDPAU_MPEG2;
        case CODEC_ID_WMV3:
            return PIX_FMT_VDPAU_WMV3;
        case CODEC_ID_VC1:
            return PIX_FMT_VDPAU_VC1;
        default:
            return pFmt[0];
    }
}

vdpau_render_state* VDPAUDecoder::getFreeRenderState()
{
    for (unsigned i = 0; i < m_RenderStates.size(); i++) {
        vdpau_render_state* pRenderState = m_RenderStates[i];
        if (!(pRenderState->state & FF_VDPAU_STATE_USED_FOR_REFERENCE)) {
            return m_RenderStates[i];
        }
    }

    // No free surfaces available -> create new surface
    vdpau_render_state* pRenderState = new vdpau_render_state;
    memset(pRenderState, 0, sizeof(vdpau_render_state));
    pRenderState->surface = VDP_INVALID_HANDLE;
    VdpStatus status = vdp_video_surface_create(getVDPAUDevice(), VDP_CHROMA_TYPE_420,
            m_Size.x, m_Size.y, &pRenderState->surface);
    AVG_ASSERT(status == VDP_STATUS_OK);

    return pRenderState;
}

int VDPAUDecoder::getBufferInternal(AVCodecContext* pContext, AVFrame* pFrame)
{
    vdpau_render_state* pRenderState = getFreeRenderState();
    pFrame->data[0] = (uint8_t*)pRenderState;
    pFrame->type = FF_BUFFER_TYPE_USER;

    pRenderState->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE;
    return 0;
}

void VDPAUDecoder::render(AVCodecContext* pContext, const AVFrame* pFrame)
{
    vdpau_render_state* pRenderState = (vdpau_render_state*)pFrame->data[0];

    if (m_VDPDecoder == VDP_INVALID_HANDLE) {
        setupDecoder(pContext);
    }

    VdpStatus status = vdp_decoder_render(m_VDPDecoder, pRenderState->surface,
            (VdpPictureInfo const*)&(pRenderState->info),
            pRenderState->bitstream_buffers_used, pRenderState->bitstream_buffers);
    AVG_ASSERT(status == VDP_STATUS_OK);
}

void VDPAUDecoder::setupDecoder(AVCodecContext* pContext)
{
    VdpStatus status;

    // Create new decoder and mixer.
    VdpDecoderProfile profile = 0;
    switch (pContext->pix_fmt) {
        case PIX_FMT_VDPAU_MPEG1:
            profile = VDP_DECODER_PROFILE_MPEG1;
            break;
        case PIX_FMT_VDPAU_MPEG2:
            profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
            break;
        case PIX_FMT_VDPAU_H264:
            profile = VDP_DECODER_PROFILE_H264_HIGH;
            break;
        case PIX_FMT_VDPAU_WMV3:
            profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
            break;
        case PIX_FMT_VDPAU_VC1:
            profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
            break;
        default:
            AVG_ASSERT(false);
    }
    status = vdp_decoder_create(getVDPAUDevice(), profile, m_Size.x, m_Size.y, 16,
            &m_VDPDecoder);
    AVG_ASSERT(status == VDP_STATUS_OK);

    m_PixFmt = pContext->pix_fmt;

    VdpVideoMixerFeature features[] = {
        VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL,
        VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL,
    };
    VdpVideoMixerParameter params[] = {
        VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
        VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
        VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE,
        VDP_VIDEO_MIXER_PARAMETER_LAYERS
    };
    VdpChromaType chroma = VDP_CHROMA_TYPE_420;
    int  numLayers = 0;
    void const* paramValues [] = { &m_Size.x, &m_Size.y, &chroma, &numLayers };

    status = vdp_video_mixer_create(getVDPAUDevice(), 2, features, 4, params,
            paramValues, &m_VDPMixer);
    AVG_ASSERT(status == VDP_STATUS_OK);

}

}

<|endoftext|>