<commit_before>#include "kwm.h"

extern uint32_t MaxDisplayCount;
extern uint32_t ActiveDisplaysCount;
extern CGDirectDisplayID ActiveDisplays[];

extern screen_info *Screen;
extern int CurrentSpace;

extern std::map<unsigned int, screen_info> DisplayMap;
extern std::vector<window_info> WindowLst;
extern std::vector<window_info> FloatingAppLst;
extern window_info *FocusedWindow;

extern int DefaultPaddingLeft, DefaultPaddingRight;
extern int DefaultPaddingTop, DefaultPaddingBottom;
extern int DefaultGapVertical, DefaultGapHorizontal;

extern pthread_mutex_t BackgroundLock;

void DisplayReconfigurationCallBack(CGDirectDisplayID Display, CGDisplayChangeSummaryFlags Flags, void *UserInfo)
{
    if (Flags & kCGDisplayAddFlag)
    {
        // Display has been added
        DEBUG("New display detected! DisplayID: " << Display << " Index: " << ActiveDisplaysCount)

        DisplayMap[Display] = CreateDefaultScreenInfo(Display, ActiveDisplaysCount++);
    }
    else if (Flags & kCGDisplayRemoveFlag)
    {
        // Display has been removed
        DEBUG("Display has been removed! DisplayID: " << Display)

        std::map<int, space_info>::iterator It;
        for(It = DisplayMap[Display].Space.begin(); It != DisplayMap[Display].Space.end(); ++It)
            DestroyNodeTree(It->second.RootNode);

        DisplayMap.erase(Display);
        RefreshActiveDisplays();
    }
}

screen_info CreateDefaultScreenInfo(int DisplayIndex, int ScreenIndex)
{
    CGRect DisplayRect = CGDisplayBounds(DisplayIndex);
    screen_info Screen;

    Screen.ID = ScreenIndex;
    Screen.ForceContainerUpdate = false;
    Screen.ActiveSpace = -1;
    Screen.OldWindowListCount = -1;

    Screen.X = DisplayRect.origin.x;
    Screen.Y = DisplayRect.origin.y;
    Screen.Width = DisplayRect.size.width;
    Screen.Height = DisplayRect.size.height;

    Screen.PaddingTop = DefaultPaddingTop;
    Screen.PaddingLeft = DefaultPaddingLeft;
    Screen.PaddingRight = DefaultPaddingRight;
    Screen.PaddingBottom = DefaultPaddingBottom;

    Screen.VerticalGap = DefaultGapVertical;
    Screen.HorizontalGap = DefaultGapHorizontal;

    return Screen;
}

void GetActiveDisplays()
{
    CGGetActiveDisplayList(MaxDisplayCount, (CGDirectDisplayID*)&ActiveDisplays, &ActiveDisplaysCount);
    for(int DisplayIndex = 0; DisplayIndex < ActiveDisplaysCount; ++DisplayIndex)
    {
        unsigned int DisplayID = ActiveDisplays[DisplayIndex];
        DisplayMap[DisplayID] = CreateDefaultScreenInfo(DisplayID, DisplayIndex);;

        DEBUG("DisplayID " << DisplayID << " has index " << DisplayIndex)
    }

    Screen = GetDisplayOfMousePointer();
    CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallBack, NULL);
}

void RefreshActiveDisplays()
{
    CGGetActiveDisplayList(MaxDisplayCount, (CGDirectDisplayID*)&ActiveDisplays, &ActiveDisplaysCount);
    for(int DisplayIndex = 0; DisplayIndex < ActiveDisplaysCount; ++DisplayIndex)
    {
        unsigned int DisplayID = ActiveDisplays[DisplayIndex];
        std::map<unsigned int, screen_info>::iterator It;
        if(It != DisplayMap.end())
            DisplayMap[DisplayID].ID = DisplayIndex;
        else
            DisplayMap[DisplayID] = CreateDefaultScreenInfo(DisplayID, DisplayIndex);

        DEBUG("DisplayID " << DisplayID << " has index " << DisplayIndex)
    }

    Screen = GetDisplayOfMousePointer();
}

screen_info *GetDisplayFromScreenID(int ID)
{
    std::map<unsigned int, screen_info>::iterator It;
    for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
    {
        screen_info *Screen = &It->second;
        if(Screen->ID == ID)
            return Screen;
    }

    return NULL;
}

screen_info *GetDisplayOfMousePointer()
{
    CGEventRef Event = CGEventCreate(NULL);
    CGPoint Cursor = CGEventGetLocation(Event);
    CFRelease(Event);

    std::map<unsigned int, screen_info>::iterator It;
    for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
    {
        screen_info *Screen = &It->second;
        if(Cursor.x >= Screen->X && Cursor.x <= Screen->X + Screen->Width &&
           Cursor.y >= Screen->Y && Cursor.y <= Screen->Y + Screen->Height)
               return Screen;
    }

    return NULL;
}

screen_info *GetDisplayOfWindow(window_info *Window)
{
    if(Window)
    {
        std::map<unsigned int, screen_info>::iterator It;
        for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
        {
            screen_info *Screen = &It->second;
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                return Screen;
        }
    }

    return NULL;
}

std::vector<window_info*> GetAllWindowsOnDisplay(int ScreenIndex)
{
    screen_info *Screen = GetDisplayFromScreenID(ScreenIndex);
    std::vector<window_info*> ScreenWindowLst;
    for(int WindowIndex = 0; WindowIndex < WindowLst.size(); ++WindowIndex)
    {
        window_info *Window = &WindowLst[WindowIndex];
        if(!IsApplicationFloating(&WindowLst[WindowIndex]))
        {
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                ScreenWindowLst.push_back(Window);
        }
    }

    return ScreenWindowLst;
}

std::vector<int> GetAllWindowIDsOnDisplay(int ScreenIndex)
{
    screen_info *Screen = GetDisplayFromScreenID(ScreenIndex);
    std::vector<int> ScreenWindowIDLst;
    for(int WindowIndex = 0; WindowIndex < WindowLst.size(); ++WindowIndex)
    {
        window_info *Window = &WindowLst[WindowIndex];
        if(!IsApplicationFloating(&WindowLst[WindowIndex]))
        {
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                ScreenWindowIDLst.push_back(Window->WID);
        }
    }

    return ScreenWindowIDLst;
}

void SetDefaultPaddingOfDisplay(const std::string &Side, int Offset)
{
    if(Side == "left")
        DefaultPaddingLeft = Offset;
    else if(Side == "right")
        DefaultPaddingRight = Offset;
    else if(Side == "top")
        DefaultPaddingTop = Offset;
    else if(Side == "bottom")
        DefaultPaddingBottom = Offset;
}

void SetDefaultGapOfDisplay(const std::string &Side, int Offset)
{
    if(Side == "vertical")
        DefaultGapVertical = Offset;
    else if(Side == "horizontal")
        DefaultGapHorizontal = Offset;
}

void ChangePaddingOfDisplay(const std::string &Side, int Offset)
{
    screen_info *Screen = GetDisplayOfMousePointer();
    if(Side == "left")
        Screen->Space[CurrentSpace].PaddingLeft += Offset;
    else if(Side == "right")
        Screen->Space[CurrentSpace].PaddingRight += Offset;
    else if(Side == "top")
        Screen->Space[CurrentSpace].PaddingTop += Offset;
    else if(Side == "bottom")
        Screen->Space[CurrentSpace].PaddingBottom += Offset;

    SetRootNodeContainer(Screen, Screen->Space[CurrentSpace].RootNode);
    CreateNodeContainers(Screen, Screen->Space[CurrentSpace].RootNode, true);
    ApplyNodeContainer(Screen->Space[CurrentSpace].RootNode);
}

void ChangeGapOfDisplay(const std::string &Side, int Offset)
{
    screen_info *Screen = GetDisplayOfMousePointer();
    if(Side == "vertical")
        Screen->Space[CurrentSpace].VerticalGap += Offset;
    else if(Side == "horizontal")
        Screen->Space[CurrentSpace].HorizontalGap += Offset;

    CreateNodeContainers(Screen, Screen->Space[CurrentSpace].RootNode, true);
    ApplyNodeContainer(Screen->Space[CurrentSpace].RootNode);
}

void CycleFocusedWindowDisplay(int Shift)
{
    screen_info *Screen = GetDisplayOfWindow(FocusedWindow);
    int NewScreenIndex = -1;

    if(Shift == 1)
    {
        NewScreenIndex = (Screen->ID + 1 >= ActiveDisplaysCount) ? 0 : Screen->ID + 1;
    }
    else if(Shift == -1)
    {
        NewScreenIndex = (Screen->ID - 1 < 0) ? ActiveDisplaysCount - 1 : Screen->ID - 1;
    }

    if(NewScreenIndex != Screen->ID)
    {
        screen_info *NewScreen = GetDisplayFromScreenID(NewScreenIndex);
        AddWindowToTreeOfUnfocusedMonitor(NewScreen);
    }
}
<commit_msg>gaps and screen padding can no longer go below 0<commit_after>#include "kwm.h"

extern uint32_t MaxDisplayCount;
extern uint32_t ActiveDisplaysCount;
extern CGDirectDisplayID ActiveDisplays[];

extern screen_info *Screen;
extern int CurrentSpace;

extern std::map<unsigned int, screen_info> DisplayMap;
extern std::vector<window_info> WindowLst;
extern std::vector<window_info> FloatingAppLst;
extern window_info *FocusedWindow;

extern int DefaultPaddingLeft, DefaultPaddingRight;
extern int DefaultPaddingTop, DefaultPaddingBottom;
extern int DefaultGapVertical, DefaultGapHorizontal;

extern pthread_mutex_t BackgroundLock;

void DisplayReconfigurationCallBack(CGDirectDisplayID Display, CGDisplayChangeSummaryFlags Flags, void *UserInfo)
{
    pthread_mutex_lock(&BackgroundLock);

    if (Flags & kCGDisplayAddFlag)
    {
        // Display has been added
        DEBUG("New display detected! DisplayID: " << Display << " Index: " << ActiveDisplaysCount)

        DisplayMap[Display] = CreateDefaultScreenInfo(Display, ActiveDisplaysCount++);
    }
    else if (Flags & kCGDisplayRemoveFlag)
    {
        // Display has been removed
        DEBUG("Display has been removed! DisplayID: " << Display)

        std::map<int, space_info>::iterator It;
        for(It = DisplayMap[Display].Space.begin(); It != DisplayMap[Display].Space.end(); ++It)
            DestroyNodeTree(It->second.RootNode);

        DisplayMap.erase(Display);
        RefreshActiveDisplays();
    }

    pthread_mutex_unlock(&BackgroundLock);
}

screen_info CreateDefaultScreenInfo(int DisplayIndex, int ScreenIndex)
{
    CGRect DisplayRect = CGDisplayBounds(DisplayIndex);
    screen_info Screen;

    Screen.ID = ScreenIndex;
    Screen.ForceContainerUpdate = false;
    Screen.ActiveSpace = -1;
    Screen.OldWindowListCount = -1;

    Screen.X = DisplayRect.origin.x;
    Screen.Y = DisplayRect.origin.y;
    Screen.Width = DisplayRect.size.width;
    Screen.Height = DisplayRect.size.height;

    Screen.PaddingTop = DefaultPaddingTop;
    Screen.PaddingLeft = DefaultPaddingLeft;
    Screen.PaddingRight = DefaultPaddingRight;
    Screen.PaddingBottom = DefaultPaddingBottom;

    Screen.VerticalGap = DefaultGapVertical;
    Screen.HorizontalGap = DefaultGapHorizontal;

    return Screen;
}

void GetActiveDisplays()
{
    CGGetActiveDisplayList(MaxDisplayCount, (CGDirectDisplayID*)&ActiveDisplays, &ActiveDisplaysCount);
    for(int DisplayIndex = 0; DisplayIndex < ActiveDisplaysCount; ++DisplayIndex)
    {
        unsigned int DisplayID = ActiveDisplays[DisplayIndex];
        DisplayMap[DisplayID] = CreateDefaultScreenInfo(DisplayID, DisplayIndex);;

        DEBUG("DisplayID " << DisplayID << " has index " << DisplayIndex)
    }

    Screen = GetDisplayOfMousePointer();
    CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallBack, NULL);
}

void RefreshActiveDisplays()
{
    CGGetActiveDisplayList(MaxDisplayCount, (CGDirectDisplayID*)&ActiveDisplays, &ActiveDisplaysCount);
    for(int DisplayIndex = 0; DisplayIndex < ActiveDisplaysCount; ++DisplayIndex)
    {
        unsigned int DisplayID = ActiveDisplays[DisplayIndex];
        std::map<unsigned int, screen_info>::iterator It;
        if(It != DisplayMap.end())
            DisplayMap[DisplayID].ID = DisplayIndex;
        else
            DisplayMap[DisplayID] = CreateDefaultScreenInfo(DisplayID, DisplayIndex);

        DEBUG("DisplayID " << DisplayID << " has index " << DisplayIndex)
    }

    Screen = GetDisplayOfMousePointer();
}

screen_info *GetDisplayFromScreenID(int ID)
{
    std::map<unsigned int, screen_info>::iterator It;
    for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
    {
        screen_info *Screen = &It->second;
        if(Screen->ID == ID)
            return Screen;
    }

    return NULL;
}

screen_info *GetDisplayOfMousePointer()
{
    CGEventRef Event = CGEventCreate(NULL);
    CGPoint Cursor = CGEventGetLocation(Event);
    CFRelease(Event);

    std::map<unsigned int, screen_info>::iterator It;
    for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
    {
        screen_info *Screen = &It->second;
        if(Cursor.x >= Screen->X && Cursor.x <= Screen->X + Screen->Width &&
           Cursor.y >= Screen->Y && Cursor.y <= Screen->Y + Screen->Height)
               return Screen;
    }

    return NULL;
}

screen_info *GetDisplayOfWindow(window_info *Window)
{
    if(Window)
    {
        std::map<unsigned int, screen_info>::iterator It;
        for(It = DisplayMap.begin(); It != DisplayMap.end(); ++It)
        {
            screen_info *Screen = &It->second;
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                return Screen;
        }
    }

    return NULL;
}

std::vector<window_info*> GetAllWindowsOnDisplay(int ScreenIndex)
{
    screen_info *Screen = GetDisplayFromScreenID(ScreenIndex);
    std::vector<window_info*> ScreenWindowLst;
    for(int WindowIndex = 0; WindowIndex < WindowLst.size(); ++WindowIndex)
    {
        window_info *Window = &WindowLst[WindowIndex];
        if(!IsApplicationFloating(&WindowLst[WindowIndex]))
        {
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                ScreenWindowLst.push_back(Window);
        }
    }

    return ScreenWindowLst;
}

std::vector<int> GetAllWindowIDsOnDisplay(int ScreenIndex)
{
    screen_info *Screen = GetDisplayFromScreenID(ScreenIndex);
    std::vector<int> ScreenWindowIDLst;
    for(int WindowIndex = 0; WindowIndex < WindowLst.size(); ++WindowIndex)
    {
        window_info *Window = &WindowLst[WindowIndex];
        if(!IsApplicationFloating(&WindowLst[WindowIndex]))
        {
            if(Window->X >= Screen->X && Window->X <= Screen->X + Screen->Width)
                ScreenWindowIDLst.push_back(Window->WID);
        }
    }

    return ScreenWindowIDLst;
}

void SetDefaultPaddingOfDisplay(const std::string &Side, int Offset)
{
    if(Side == "left")
        DefaultPaddingLeft = Offset;
    else if(Side == "right")
        DefaultPaddingRight = Offset;
    else if(Side == "top")
        DefaultPaddingTop = Offset;
    else if(Side == "bottom")
        DefaultPaddingBottom = Offset;
}

void SetDefaultGapOfDisplay(const std::string &Side, int Offset)
{
    if(Side == "vertical")
        DefaultGapVertical = Offset;
    else if(Side == "horizontal")
        DefaultGapHorizontal = Offset;
}

void ChangePaddingOfDisplay(const std::string &Side, int Offset)
{
    screen_info *Screen = GetDisplayOfMousePointer();
    if(Side == "left")
    {
        if(Screen->Space[CurrentSpace].PaddingLeft + Offset >= 0)
            Screen->Space[CurrentSpace].PaddingLeft += Offset;
    }
    else if(Side == "right")
    {
        if(Screen->Space[CurrentSpace].PaddingRight + Offset >= 0)
            Screen->Space[CurrentSpace].PaddingRight += Offset;
    }
    else if(Side == "top")
    {
        if(Screen->Space[CurrentSpace].PaddingTop + Offset >= 0)
            Screen->Space[CurrentSpace].PaddingTop += Offset;
    }
    else if(Side == "bottom")
    {
        if(Screen->Space[CurrentSpace].PaddingBottom + Offset >= 0)
            Screen->Space[CurrentSpace].PaddingBottom += Offset;
    }

    SetRootNodeContainer(Screen, Screen->Space[CurrentSpace].RootNode);
    CreateNodeContainers(Screen, Screen->Space[CurrentSpace].RootNode, true);
    ApplyNodeContainer(Screen->Space[CurrentSpace].RootNode);
}

void ChangeGapOfDisplay(const std::string &Side, int Offset)
{
    screen_info *Screen = GetDisplayOfMousePointer();
    if(Side == "vertical")
    {
        if(Screen->Space[CurrentSpace].VerticalGap + Offset >= 0)
            Screen->Space[CurrentSpace].VerticalGap += Offset;
    }
    else if(Side == "horizontal")
    {
        if(Screen->Space[CurrentSpace].HorizontalGap + Offset >= 0)
            Screen->Space[CurrentSpace].HorizontalGap += Offset;
    }

    CreateNodeContainers(Screen, Screen->Space[CurrentSpace].RootNode, true);
    ApplyNodeContainer(Screen->Space[CurrentSpace].RootNode);
}

void CycleFocusedWindowDisplay(int Shift)
{
    screen_info *Screen = GetDisplayOfWindow(FocusedWindow);
    int NewScreenIndex = -1;

    if(Shift == 1)
    {
        NewScreenIndex = (Screen->ID + 1 >= ActiveDisplaysCount) ? 0 : Screen->ID + 1;
    }
    else if(Shift == -1)
    {
        NewScreenIndex = (Screen->ID - 1 < 0) ? ActiveDisplaysCount - 1 : Screen->ID - 1;
    }

    if(NewScreenIndex != Screen->ID)
    {
        screen_info *NewScreen = GetDisplayFromScreenID(NewScreenIndex);
        AddWindowToTreeOfUnfocusedMonitor(NewScreen);
    }
}
<|endoftext|>


<commit_before>#include "cmm_socket.private.h"
#include "csocket.h"
#include "debug.h"
#include "timeops.h"
#include "cmm_socket_control.h"
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "csocket_sender.h"
#include "csocket_receiver.h"
#include "csocket_mapping.h"
#include <functional>
using std::min; using std::max;

CSocketPtr
CSocket::create(boost::weak_ptr<CMMSocketImpl> sk_,
                struct net_interface local_iface_,
                struct net_interface remote_iface_,
                int accepted_sock)
{
    CSocketPtr new_csock(new CSocket(sk_, local_iface_,
                                     remote_iface_, accepted_sock));
    new_csock->self_ptr = new_csock;
    return new_csock;
}

CSocket::CSocket(boost::weak_ptr<CMMSocketImpl> sk_,
                 struct net_interface local_iface_,
                 struct net_interface remote_iface_,
                 int accepted_sock)
    : sk(sk_),
      local_iface(local_iface_), remote_iface(remote_iface_),
      csock_sendr(NULL), csock_recvr(NULL), irob_indexes(local_iface_.labels)
{
    assert(sk);
    if (accepted_sock == -1) {
        osfd = socket(sk->sock_family, sk->sock_type, sk->sock_protocol);
        if (osfd < 0) {
            /* out of file descriptors or memory at this point */
            throw std::runtime_error("Out of FDs or memory!");
        }

        sk->set_all_sockopts(osfd);
    } else {
        osfd = accepted_sock;
    }

    int on = 1;
    int rc;
    /* Make sure that this socket is TCP_NODELAY for good performance */
    struct protoent *pe = getprotobyname("TCP");
    if (pe) {
	rc = setsockopt (osfd, pe->p_proto, TCP_NODELAY,
			 (char *) &on, sizeof(on));
    } else {
	rc = setsockopt (osfd, 6, TCP_NODELAY,
			 (char *) &on, sizeof(on));
    }
    if (rc < 0) {
	dbgprintf("Cannot make socket TCP_NODELAY");
    }
}

CSocket::~CSocket()
{
    dbgprintf("CSocket %d is being destroyed\n", osfd);
    if (osfd > 0) {
	/* if it's a real open socket */
        assert(csock_sendr == NULL && csock_recvr == NULL);
	close(osfd);
    }
}

int
CSocket::phys_connect()
{
    struct sockaddr_in local_addr, remote_addr;

    // XXX-TODO: don't assume it's an inet socket

    local_addr.sin_family = AF_INET;
    local_addr.sin_addr = local_iface.ip_addr;
    local_addr.sin_port = 0;

    remote_addr.sin_family = AF_INET;
    remote_addr.sin_addr = remote_iface.ip_addr;
    remote_addr.sin_port = sk->remote_listener_port;

    int rc = bind(osfd, (struct sockaddr *)&local_addr,
              sizeof(local_addr));
    if (rc < 0) {
	perror("bind");
	dbgprintf("Failed to bind osfd %d to %s:%d\n",
		  osfd, inet_ntoa(local_addr.sin_addr),
		  ntohs(local_addr.sin_port));
	return rc;
    }
    dbgprintf("Successfully bound osfd %d to %s:%d\n",
	      osfd, inet_ntoa(local_addr.sin_addr),
	      ntohs(local_addr.sin_port));

    rc = connect(osfd, (struct sockaddr *)&remote_addr,
		 sizeof(remote_addr));
    if (rc < 0) {
	perror("connect");
	dbgprintf("Failed to connect osfd %d to %s:%d\n",
		  osfd, inet_ntoa(remote_addr.sin_addr),
		  ntohs(remote_addr.sin_port));
	return rc;
    }
    struct CMMSocketControlHdr hdr;
    memset(&hdr, 0, sizeof(hdr));
    hdr.type = htons(CMM_CONTROL_MSG_NEW_INTERFACE);
    hdr.send_labels = 0;
    hdr.op.new_interface.ip_addr = local_iface.ip_addr;
    hdr.op.new_interface.labels = htonl(local_iface.labels);
    rc = send(osfd, &hdr, sizeof(hdr), 0);
    if (rc != sizeof(hdr)) {
        perror("send");
        dbgprintf("Failed to send interface info\n");
        return rc;
    }

    startup_workers();
    return 0;
}

void
CSocket::startup_workers()
{
    if (!csock_sendr && !csock_recvr) {
	csock_sendr = new CSocketSender(CSocketPtr(self_ptr));
	csock_recvr = new CSocketReceiver(CSocketPtr(self_ptr));
	int rc = csock_sendr->start();
        if (rc != 0) {
            throw std::runtime_error("Failed to create csocket_sender thread!");
        }
	rc = csock_recvr->start();
        if (rc != 0) {
            throw std::runtime_error("Failed to create csocket_receiver thread!");
        }
    }
}

bool
CSocket::matches(u_long send_labels)
{
    return sk->csock_map->csock_matches(this, send_labels);
}

u_long
CSocket::bandwidth()
{
    // TODO: replace with measurement on this socket
    return min(local_iface.bandwidth, remote_iface.bandwidth);
}

double CSocket::RTT()
{
    // TODO: replace with measurement on this socket
    return (local_iface.RTT / 2.0) + (remote_iface.RTT / 2.0);
}

#define useconds(tv) ((tv).tv_sec*1000000 + (tv).tv_usec)

ssize_t
CSocket::trickle_chunksize(struct timeval time_since_last_fg,
                           struct timeval bg_wait_time)
{
    const ssize_t max_chunksize = bandwidth();
    const ssize_t min_chunksize = max(max_chunksize / 16, 64);
    ssize_t chunksize = min_chunksize * (1 << (useconds(time_since_last_fg) /
                                               useconds(sk->bg_wait_time())*2));
    if (chunksize < 0) {
        chunksize = max_chunksize;
    }
    chunksize = max(chunksize, min_chunksize);
    chunksize = min(chunksize, max_chunksize);
    return chunksize;
}
<commit_msg>Corrected RTT calculation.<commit_after>#include "cmm_socket.private.h"
#include "csocket.h"
#include "debug.h"
#include "timeops.h"
#include "cmm_socket_control.h"
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "csocket_sender.h"
#include "csocket_receiver.h"
#include "csocket_mapping.h"
#include <functional>
using std::min; using std::max;

CSocketPtr
CSocket::create(boost::weak_ptr<CMMSocketImpl> sk_,
                struct net_interface local_iface_,
                struct net_interface remote_iface_,
                int accepted_sock)
{
    CSocketPtr new_csock(new CSocket(sk_, local_iface_,
                                     remote_iface_, accepted_sock));
    new_csock->self_ptr = new_csock;
    return new_csock;
}

CSocket::CSocket(boost::weak_ptr<CMMSocketImpl> sk_,
                 struct net_interface local_iface_,
                 struct net_interface remote_iface_,
                 int accepted_sock)
    : sk(sk_),
      local_iface(local_iface_), remote_iface(remote_iface_),
      csock_sendr(NULL), csock_recvr(NULL), irob_indexes(local_iface_.labels)
{
    assert(sk);
    if (accepted_sock == -1) {
        osfd = socket(sk->sock_family, sk->sock_type, sk->sock_protocol);
        if (osfd < 0) {
            /* out of file descriptors or memory at this point */
            throw std::runtime_error("Out of FDs or memory!");
        }

        sk->set_all_sockopts(osfd);
    } else {
        osfd = accepted_sock;
    }

    int on = 1;
    int rc;
    /* Make sure that this socket is TCP_NODELAY for good performance */
    struct protoent *pe = getprotobyname("TCP");
    if (pe) {
	rc = setsockopt (osfd, pe->p_proto, TCP_NODELAY,
			 (char *) &on, sizeof(on));
    } else {
	rc = setsockopt (osfd, 6, TCP_NODELAY,
			 (char *) &on, sizeof(on));
    }
    if (rc < 0) {
	dbgprintf("Cannot make socket TCP_NODELAY");
    }
}

CSocket::~CSocket()
{
    dbgprintf("CSocket %d is being destroyed\n", osfd);
    if (osfd > 0) {
	/* if it's a real open socket */
        assert(csock_sendr == NULL && csock_recvr == NULL);
	close(osfd);
    }
}

int
CSocket::phys_connect()
{
    struct sockaddr_in local_addr, remote_addr;

    // XXX-TODO: don't assume it's an inet socket

    local_addr.sin_family = AF_INET;
    local_addr.sin_addr = local_iface.ip_addr;
    local_addr.sin_port = 0;

    remote_addr.sin_family = AF_INET;
    remote_addr.sin_addr = remote_iface.ip_addr;
    remote_addr.sin_port = sk->remote_listener_port;

    int rc = bind(osfd, (struct sockaddr *)&local_addr,
              sizeof(local_addr));
    if (rc < 0) {
	perror("bind");
	dbgprintf("Failed to bind osfd %d to %s:%d\n",
		  osfd, inet_ntoa(local_addr.sin_addr),
		  ntohs(local_addr.sin_port));
	return rc;
    }
    dbgprintf("Successfully bound osfd %d to %s:%d\n",
	      osfd, inet_ntoa(local_addr.sin_addr),
	      ntohs(local_addr.sin_port));

    rc = connect(osfd, (struct sockaddr *)&remote_addr,
		 sizeof(remote_addr));
    if (rc < 0) {
	perror("connect");
	dbgprintf("Failed to connect osfd %d to %s:%d\n",
		  osfd, inet_ntoa(remote_addr.sin_addr),
		  ntohs(remote_addr.sin_port));
	return rc;
    }
    struct CMMSocketControlHdr hdr;
    memset(&hdr, 0, sizeof(hdr));
    hdr.type = htons(CMM_CONTROL_MSG_NEW_INTERFACE);
    hdr.send_labels = 0;
    hdr.op.new_interface.ip_addr = local_iface.ip_addr;
    hdr.op.new_interface.labels = htonl(local_iface.labels);
    rc = send(osfd, &hdr, sizeof(hdr), 0);
    if (rc != sizeof(hdr)) {
        perror("send");
        dbgprintf("Failed to send interface info\n");
        return rc;
    }

    startup_workers();
    return 0;
}

void
CSocket::startup_workers()
{
    if (!csock_sendr && !csock_recvr) {
	csock_sendr = new CSocketSender(CSocketPtr(self_ptr));
	csock_recvr = new CSocketReceiver(CSocketPtr(self_ptr));
	int rc = csock_sendr->start();
        if (rc != 0) {
            throw std::runtime_error("Failed to create csocket_sender thread!");
        }
	rc = csock_recvr->start();
        if (rc != 0) {
            throw std::runtime_error("Failed to create csocket_receiver thread!");
        }
    }
}

bool
CSocket::matches(u_long send_labels)
{
    return sk->csock_map->csock_matches(this, send_labels);
}

u_long
CSocket::bandwidth()
{
    // TODO: replace with measurement on this socket
    return min(local_iface.bandwidth, remote_iface.bandwidth);
}

double CSocket::RTT()
{
    // TODO: replace with measurement on this socket
    return 2*((local_iface.RTT / 2.0) + (remote_iface.RTT / 2.0));
}

#define useconds(tv) ((tv).tv_sec*1000000 + (tv).tv_usec)

ssize_t
CSocket::trickle_chunksize(struct timeval time_since_last_fg,
                           struct timeval bg_wait_time)
{
    const ssize_t max_chunksize = bandwidth();
    const ssize_t min_chunksize = max(max_chunksize / 16, 64);
    ssize_t chunksize = min_chunksize * (1 << (useconds(time_since_last_fg) /
                                               useconds(sk->bg_wait_time())*2));
    if (chunksize < 0) {
        chunksize = max_chunksize;
    }
    chunksize = max(chunksize, min_chunksize);
    chunksize = min(chunksize, max_chunksize);
    return chunksize;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formsimp.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 10:36:16 $
 *
 *  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_xmloff.hxx"

#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HPP_
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_ANIMIMP_HXX
#include "formsimp.hxx"
#endif

using namespace ::rtl;

TYPEINIT1( XMLFormsContext, SvXMLImportContext );

XMLFormsContext::XMLFormsContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName )
: SvXMLImportContext(rImport, nPrfx, rLocalName)
{
}

XMLFormsContext::~XMLFormsContext()
{
}

SvXMLImportContext * XMLFormsContext::CreateChildContext( USHORT nPrefix, const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    return GetImport().GetFormImport()->createContext( nPrefix, rLocalName, xAttrList );
}
<commit_msg>INTEGRATION: CWS vgbugs07 (1.5.124); FILE MERGED 2007/06/04 13:23:26 vg 1.5.124.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formsimp.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:16:05 $
 *
 *  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_xmloff.hxx"

#ifndef _COM_SUN_STAR_XML_SAX_XATTRIBUTELIST_HPP_
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _XMLOFF_ANIMIMP_HXX
#include <xmloff/formsimp.hxx>
#endif

using namespace ::rtl;

TYPEINIT1( XMLFormsContext, SvXMLImportContext );

XMLFormsContext::XMLFormsContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName )
: SvXMLImportContext(rImport, nPrfx, rLocalName)
{
}

XMLFormsContext::~XMLFormsContext()
{
}

SvXMLImportContext * XMLFormsContext::CreateChildContext( USHORT nPrefix, const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    return GetImport().GetFormImport()->createContext( nPrefix, rLocalName, xAttrList );
}
<|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/channel.h"

#include <chrono>
#include <thread>

#include "gtest/gtest.h"

using paddle::framework::Channel;
using paddle::framework::MakeChannel;
using paddle::framework::CloseChannel;

TEST(Channel, MakeAndClose) {
  using paddle::framework::details::Buffered;
  using paddle::framework::details::UnBuffered;
  {
    // MakeChannel should return a buffered channel is buffer_size > 0.
    auto ch = MakeChannel<int>(10);
    EXPECT_NE(dynamic_cast<Buffered<int>*>(ch), nullptr);
    EXPECT_EQ(dynamic_cast<UnBuffered<int>*>(ch), nullptr);
    CloseChannel(ch);
    delete ch;
  }
  {
    // MakeChannel should return an un-buffered channel is buffer_size = 0.
    auto ch = MakeChannel<int>(0);
    EXPECT_EQ(dynamic_cast<Buffered<int>*>(ch), nullptr);
    EXPECT_NE(dynamic_cast<UnBuffered<int>*>(ch), nullptr);
    CloseChannel(ch);
    delete ch;
  }
}

TEST(Channel, SufficientBufferSizeDoesntBlock) {
  const size_t buffer_size = 10;
  auto ch = MakeChannel<size_t>(buffer_size);
  for (size_t i = 0; i < buffer_size; ++i) {
    ch->Send(&i);  // should not block
  }

  size_t out;
  for (size_t i = 0; i < buffer_size; ++i) {
    ch->Receive(&out);  // should not block
    EXPECT_EQ(out, i);
  }
  CloseChannel(ch);
  delete ch;
}

TEST(Channel, ConcurrentSendNonConcurrentReceiveWithSufficientBufferSize) {
  const size_t buffer_size = 10;
  auto ch = MakeChannel<size_t>(buffer_size);
  size_t sum = 0;
  std::thread t([&]() {
    // Try to write more than buffer size.
    for (size_t i = 0; i < 2 * buffer_size; ++i) {
      ch->Send(&i);  // should not block
      sum += i;
    }
  });
  std::this_thread::sleep_for(std::chrono::milliseconds(100));  // wait 0.5 sec
  EXPECT_EQ(sum, 45U);

  CloseChannel(ch);
  t.join();
  delete ch;
}

TEST(Channel, SimpleUnbufferedChannelTest) {
  auto ch = MakeChannel<int>(0);
  unsigned sum_send = 0;
  std::thread t([&]() {
    for (int i = 0; i < 5; i++) {
      ch->Send(&i);
      sum_send += i;
    }
  });
  for (int i = 0; i < 5; i++) {
    int recv;
    ch->Receive(&recv);
    EXPECT_EQ(recv, i);
  }

  CloseChannel(ch);
  t.join();
  EXPECT_EQ(sum_send, 10U);
  delete ch;
}
<commit_msg>Add unit test with less receivers, more senders for unbuffered channel. (#8060)<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/channel.h"

#include <chrono>
#include <thread>

#include "gtest/gtest.h"

using paddle::framework::Channel;
using paddle::framework::MakeChannel;
using paddle::framework::CloseChannel;

TEST(Channel, MakeAndClose) {
  using paddle::framework::details::Buffered;
  using paddle::framework::details::UnBuffered;
  {
    // MakeChannel should return a buffered channel is buffer_size > 0.
    auto ch = MakeChannel<int>(10);
    EXPECT_NE(dynamic_cast<Buffered<int>*>(ch), nullptr);
    EXPECT_EQ(dynamic_cast<UnBuffered<int>*>(ch), nullptr);
    CloseChannel(ch);
    delete ch;
  }
  {
    // MakeChannel should return an un-buffered channel is buffer_size = 0.
    auto ch = MakeChannel<int>(0);
    EXPECT_EQ(dynamic_cast<Buffered<int>*>(ch), nullptr);
    EXPECT_NE(dynamic_cast<UnBuffered<int>*>(ch), nullptr);
    CloseChannel(ch);
    delete ch;
  }
}

TEST(Channel, SufficientBufferSizeDoesntBlock) {
  const size_t buffer_size = 10;
  auto ch = MakeChannel<size_t>(buffer_size);
  for (size_t i = 0; i < buffer_size; ++i) {
    ch->Send(&i);  // should not block
  }

  size_t out;
  for (size_t i = 0; i < buffer_size; ++i) {
    ch->Receive(&out);  // should not block
    EXPECT_EQ(out, i);
  }
  CloseChannel(ch);
  delete ch;
}

TEST(Channel, ConcurrentSendNonConcurrentReceiveWithSufficientBufferSize) {
  const size_t buffer_size = 10;
  auto ch = MakeChannel<size_t>(buffer_size);
  size_t sum = 0;
  std::thread t([&]() {
    // Try to write more than buffer size.
    for (size_t i = 0; i < 2 * buffer_size; ++i) {
      ch->Send(&i);  // should not block
      sum += i;
    }
  });
  std::this_thread::sleep_for(std::chrono::milliseconds(100));  // wait 0.5 sec
  EXPECT_EQ(sum, 45U);

  CloseChannel(ch);
  t.join();
  delete ch;
}

TEST(Channel, SimpleUnbufferedChannelTest) {
  auto ch = MakeChannel<int>(0);
  unsigned sum_send = 0;
  std::thread t([&]() {
    for (int i = 0; i < 5; i++) {
      ch->Send(&i);
      sum_send += i;
    }
  });
  for (int i = 0; i < 5; i++) {
    int recv;
    ch->Receive(&recv);
    EXPECT_EQ(recv, i);
  }

  CloseChannel(ch);
  t.join();
  EXPECT_EQ(sum_send, 10U);
  delete ch;
}

TEST(Channel, UnbufferedLessReceiveMoreSendTest) {
  auto ch = MakeChannel<int>(0);
  unsigned sum_send = 0;
  // Send should block after three iterations
  // since we only have three receivers.
  std::thread t([&]() {
    // Try to send more number of times
    // than receivers
    for (int i = 0; i < 4; i++) {
      ch->Send(&i);
      sum_send += i;
    }
  });
  for (int i = 0; i < 3; i++) {
    int recv;
    ch->Receive(&recv);
    EXPECT_EQ(recv, i);
  }
  std::this_thread::sleep_for(std::chrono::milliseconds(100));  // wait 0.5 sec
  EXPECT_EQ(sum_send, 3U);

  CloseChannel(ch);
  t.join();
  delete ch;
}
<|endoftext|>


<commit_before>#ifdef MESOS_WEBUI

#include <Python.h>

#include <tr1/functional>

#include "common/strings.hpp"
#include "common/thread.hpp"
#include "common/utils.hpp"
#include "common/webui_utils.hpp"

namespace mesos {
namespace internal {
namespace utils {
namespace webui {

static void run(const std::string& directory,
                const std::string& script,
                const std::vector<std::string>& args)
{
  // Setup the Python interpreter and load the script.
  std::string path = directory + "/" + script;

  Py_Initialize();

  // Setup argv for Python interpreter.
  char** argv = new char*[args.size() + 1];

  argv[0] = const_cast<char*>(path.c_str());

  for (int i = 0; i < args.size(); i++) {
    argv[i + 1] = const_cast<char*>(args[i].c_str());
  }

  PySys_SetArgv(args.size() + 1, argv);

  // Run some code to setup PATH and add webui_dir as a variable.
  std::string code =
    "import sys\n"
    "sys.path.append('" + directory + "/common')\n"
    "sys.path.append('" + directory + "/bottle-0.8.3')\n";

  PyRun_SimpleString(code.c_str());

  LOG(INFO) << "Loading webui script at '" << path << "'";

  FILE* file = fopen(path.c_str(), "r");
  PyRun_SimpleFile(file, path.c_str());
  fclose(file);

  Py_Finalize();

  delete[] argv;
}

void start(const Configuration& conf,
           const std::string& script,
           const std::vector<std::string>& args)
{
  // Use either a directory specified via configuration options (which
  // is necessary for running out of the build directory before 'make
  // install') or the directory determined at build time via the
  // preprocessor macro '-DMESOS_WEBUI_DIR' set in the Makefile.
  std::string directory = conf.get<std::string>("webui_dir", MESOS_WEBUI_DIR);

  // Remove any trailing '/' in directory.
  directory = strings::remove(directory, "/", strings::SUFFIX);

  // Make sure script is a relative path.
  CHECK(script[0] != '/')
    << "Expecting relative path for webui script (relative to 'webui_dir')";

  // Make sure directory/script exists.
  std::string path = directory + "/" + script;

  CHECK(utils::os::exists(path))
    << "Failed to find webui script at '" << path << "'";

  // TODO(benh): Consider actually forking a process for the webui
  // rather than just creating a thread. This will let us more easily
  // run multiple webui's simultaneously (e.g., the master and
  // slave). This might also give us better isolation from Python
  // interpreter errors (and maybe even remove the need for two C-c to
  // exit the process).

  if (!thread::start(std::tr1::bind(&run, directory, script, args), true)) {
    LOG(FATAL) << "Failed to start webui thread";
  }
}

} // namespace webui {
} // namespace utils {
} // namespace internal {
} // namespace mesos {

#endif // MESOS_WEBUI
<commit_msg>Run bottle in a separate process to avoid races with dlopen/Python (https://reviews.apache.org/r/5116).<commit_after>#ifdef MESOS_WEBUI

#include <Python.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/uio.h>

#include <tr1/functional>

#include "common/strings.hpp"
#include "common/thread.hpp"
#include "common/utils.hpp"
#include "common/webui_utils.hpp"

namespace mesos {
namespace internal {
namespace utils {
namespace webui {

static void run(const std::string& directory,
                const std::string& script,
                const std::vector<std::string>& args)
{
  // Setup the Python interpreter and load the script.
  std::string path = directory + "/" + script;

  Py_Initialize();

  // Setup argv for Python interpreter.
  char** argv = new char*[args.size() + 1];

  argv[0] = const_cast<char*>(path.c_str());

  for (int i = 0; i < args.size(); i++) {
    argv[i + 1] = const_cast<char*>(args[i].c_str());
  }

  PySys_SetArgv(args.size() + 1, argv);

  // Run some code to setup PATH and add webui_dir as a variable.
  std::string code =
    "import sys\n"
    "sys.path.append('" + directory + "/common')\n"
    "sys.path.append('" + directory + "/bottle-0.8.3')\n";

  PyRun_SimpleString(code.c_str());

  LOG(INFO) << "Loading webui script at '" << path << "'";

  FILE* file = fopen(path.c_str(), "r");
  PyRun_SimpleFile(file, path.c_str());
  fclose(file);

  Py_Finalize();

  delete[] argv;
}

void wait(int fd)
{
  char temp[8];
  if (read(fd, temp, 8) == -1) {
    PLOG(FATAL) << "Failed to read on pipe from parent";
  }
  exit(1);
}

void start(const Configuration& conf,
           const std::string& script,
           const std::vector<std::string>& args)
{
  // Use either a directory specified via configuration options (which
  // is necessary for running out of the build directory before 'make
  // install') or the directory determined at build time via the
  // preprocessor macro '-DMESOS_WEBUI_DIR' set in the Makefile.
  std::string directory = conf.get<std::string>("webui_dir", MESOS_WEBUI_DIR);

  // Remove any trailing '/' in directory.
  directory = strings::remove(directory, "/", strings::SUFFIX);

  // Make sure script is a relative path.
  CHECK(script[0] != '/')
    << "Expecting relative path for webui script (relative to 'webui_dir')";

  // Make sure directory/script exists.
  std::string path = directory + "/" + script;

  CHECK(utils::os::exists(path))
    << "Failed to find webui script at '" << path << "'";

  // TODO(benh): Consider actually forking a process for the webui
  // rather than just creating a thread. This will let us more easily
  // run multiple webui's simultaneously (e.g., the master and
  // slave). This might also give us better isolation from Python
  // interpreter errors (and maybe even remove the need for two C-c to
  // exit the process).

  int pipes[2];
  pipe(pipes);

  pid_t pid;
  if ((pid = fork()) == -1) {
    PLOG(FATAL) << "Failed to fork to launch new executor";
  }

  if (pid) {
    // In parent process.
    close(pipes[0]); // Close the reader end in the parent.
  } else {
    // In child process.
    close(pipes[1]); // Close the writer end in the child.

    if (!thread::start(std::tr1::bind(&wait, pipes[0]), true)) {
      LOG(FATAL) << "Failed to start wait thread";
    }

    run(directory, script, args);
  }

//   if (!thread::start(std::tr1::bind(&run, directory, script, args), true)) {
//     LOG(FATAL) << "Failed to start webui thread";
//   }
}

} // namespace webui {
} // namespace utils {
} // namespace internal {
} // namespace mesos {

#endif // MESOS_WEBUI
<|endoftext|>


<commit_before>#include <iostream>
#include <unistd.h>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <zookeeper.h>
#include <glog/logging.h>
#include "messages.hpp"
#include "leader_detector.hpp"
#include "ft_messaging.hpp"

namespace nexus { namespace internal {

using namespace nexus;
using namespace nexus::internal;
using namespace std;

FTMessaging *FTMessaging::getInstance() {
  if (instance==NULL)
    instance = new FTMessaging();
  return instance;
}

FTMessaging *FTMessaging::getInstance(PID _master) {
  if (instance==NULL)
    instance = new FTMessaging(_master);
  return instance;
}

FTMessaging *FTMessaging::getInstance(string _master) {
  if (instance==NULL) {
    PID mPid;
    istringstream ss(_master);
    if (!(ss >> mPid)) {
      LOG(ERROR) << "Couldn't create PID out of string in constructor.";
      return NULL;
    }
    instance = new FTMessaging(mPid);
  }
  return instance;
}

FTMessaging::FTMessaging(PID _master) :
  master(_master), msgId(0)
{
  srand(time(0));
  char s[50];
  sprintf(s, "%09i", (int)rand());
  uniqPrefix = s;
  DLOG(INFO) << "FT: Created unique FT TAG: " << s;
}

FTMessaging::FTMessaging() :
  msgId(0)
{
  srand(time(0));
  char s[50];
  sprintf(s, "%09i", (int)rand());
  uniqPrefix = s;
  DLOG(INFO) << "FT: Created unique FT TAG: " << s;
  master = {0,0,0};
}

string FTMessaging::getNextId() {
  return uniqPrefix + ":" + lexical_cast<string>(msgId++);
}

FTMessaging *FTMessaging::instance = NULL;

}}
<commit_msg>some G++ versions couldnt compile<commit_after>#include <iostream>
#include <unistd.h>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <zookeeper.h>
#include <glog/logging.h>
#include "messages.hpp"
#include "leader_detector.hpp"
#include "ft_messaging.hpp"

namespace nexus { namespace internal {

using namespace nexus;
using namespace nexus::internal;
using namespace std;

FTMessaging *FTMessaging::getInstance() {
  if (instance==NULL)
    instance = new FTMessaging();
  return instance;
}

FTMessaging *FTMessaging::getInstance(PID _master) {
  if (instance==NULL)
    instance = new FTMessaging(_master);
  return instance;
}

FTMessaging *FTMessaging::getInstance(string _master) {
  if (instance==NULL) {
    PID mPid;
    istringstream ss(_master);
    if (!(ss >> mPid)) {
      LOG(ERROR) << "Couldn't create PID out of string in constructor.";
      return NULL;
    }
    instance = new FTMessaging(mPid);
  }
  return instance;
}

FTMessaging::FTMessaging(PID _master) :
  master(_master), msgId(0)
{
  srand(time(0));
  char s[50];
  sprintf(s, "%09i", (int)rand());
  uniqPrefix = s;
  DLOG(INFO) << "FT: Created unique FT TAG: " << s;
}

FTMessaging::FTMessaging() :
  msgId(0)
{
  srand(time(0));
  char s[50];
  sprintf(s, "%09i", (int)rand());
  uniqPrefix = s;
  DLOG(INFO) << "FT: Created unique FT TAG: " << s;
}

string FTMessaging::getNextId() {
  return uniqPrefix + ":" + lexical_cast<string>(msgId++);
}

FTMessaging *FTMessaging::instance = NULL;

}}
<|endoftext|>


<commit_before>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (C) 2006 University of Edinburgh

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 Street, Fifth Floor, Boston, MA  02110-1301  USA
***********************************************************************/

#include <assert.h>
#include <limits>
#include <iostream>
#include <fstream>

#include "ngram.h"
#include "lmtable.h"
#include "dictionary.h"

#include "LanguageModel_IRST.h"
#include "TypeDef.h"
#include "Util.h"
#include "FactorCollection.h"
#include "Phrase.h"
#include "InputFileStream.h"

using namespace std;

LanguageModel_IRST::LanguageModel_IRST()
:m_lmtb(0)
{
}

LanguageModel_IRST::~LanguageModel_IRST()
{
  delete m_lmtb;
}

void LanguageModel_IRST::Load(size_t id
												, const std::string &fileName
												, FactorCollection &factorCollection
												, FactorType factorType
												, float weight
												, size_t nGramOrder)
{
	m_id					 = id;
	m_factorType 	 = factorType;
	m_weight			 = weight;
	m_nGramOrder	 = nGramOrder;

	// TODO need to be able to configure these two parameters
	int resolution = 0;   // for quantized probs
	double decay   = 0.95;
  //

	InputFileStream inp(fileName);

	m_lmtb         = new lmtable(
		inp,
		nGramOrder,
		resolution,
		decay
	);
	// LM can be ok, just outputs warnings
	CreateFactors(factorCollection);

}

void LanguageModel_IRST::CreateFactors(FactorCollection &factorCollection)
{ // add factors which have srilm id

	dict_entry *entry;
	LmId lmId;
	dictionary_iter iter(m_lmtb->dict);
	while ( (entry = iter.next()) != NULL)
	{
		LmId lmId;
    lmId.irst = entry->code;
		factorCollection.AddFactor(Output, m_factorType, entry->word, lmId);
	}

	lmId = GetLmID(BOS_);
	m_sentenceStart = factorCollection.AddFactor(Output, m_factorType, SENTENCE_START, lmId);
	lmId = GetLmID(EOS_);
	m_sentenceEnd		= factorCollection.AddFactor(Output, m_factorType, SENTENCE_END, lmId);

}

LmId LanguageModel_IRST::GetLmID( const std::string &str ) const
{
    LanguageModel_IRST *lm = const_cast<LanguageModel_IRST*>(this); // hack. not sure if supposed to cast this
    LmId res;
    res.sri = lm->m_lmtb->dict->encode( str.c_str() );
    return res;
}

float LanguageModel_IRST::GetValue(const vector<const Factor*> &contextFactor) const
{
	// set up context
	size_t count = contextFactor.size();
  ngram ng(m_lmtb->dict);
	for (size_t i = 0 ; i < count ; i++)
	{
#ifdef CDYER_DEBUG_LMSCORE
		std::cout << i <<"="<<contextFactor[i]->GetLmId().irst <<"," << contextFactor[i]->GetString()<<" ";
#endif
		ng.pushc(contextFactor[i]->GetLmId().irst);
	}
#ifdef CDYER_DEBUG_LMSCORE
	std::cout <<" (ng='" << ng << "')\n";
#endif
	return TransformScore(m_lmtb->prob(ng));
}

<commit_msg>IRST lm wrapper not compilable.<commit_after>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (C) 2006 University of Edinburgh

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 Street, Fifth Floor, Boston, MA  02110-1301  USA
***********************************************************************/

#include <assert.h>
#include <limits>
#include <iostream>
#include <fstream>

#include "ngram.h"
#include "lmtable.h"
#include "dictionary.h"

#include "LanguageModel_IRST.h"
#include "TypeDef.h"
#include "Util.h"
#include "FactorCollection.h"
#include "Phrase.h"
#include "InputFileStream.h"

using namespace std;

LanguageModel_IRST::LanguageModel_IRST()
:m_lmtb(0)
{
}

LanguageModel_IRST::~LanguageModel_IRST()
{
  delete m_lmtb;
}

void LanguageModel_IRST::Load(size_t id
												, const std::string &fileName
												, FactorCollection &factorCollection
												, FactorType factorType
												, float weight
												, size_t nGramOrder)
{
	m_id					 = id;
	m_factorType 	 = factorType;
	m_weight			 = weight;
	m_nGramOrder	 = nGramOrder;

	// TODO need to be able to configure these two parameters
	int resolution = 0;   // for quantized probs
	double decay   = 0.95;
  //

	InputFileStream inp(fileName);

	m_lmtb         = new lmtable(
		fileName.c_str(),
		nGramOrder,
		resolution,
		decay
	);
	// LM can be ok, just outputs warnings
	CreateFactors(factorCollection);

}

void LanguageModel_IRST::CreateFactors(FactorCollection &factorCollection)
{ // add factors which have srilm id

	dict_entry *entry;
	LmId lmId;
	dictionary_iter iter(m_lmtb->dict);
	while ( (entry = iter.next()) != NULL)
	{
		LmId lmId;
    lmId.irst = entry->code;
		factorCollection.AddFactor(Output, m_factorType, entry->word, lmId);
	}

	lmId = GetLmID(BOS_);
	m_sentenceStart = factorCollection.AddFactor(Output, m_factorType, SENTENCE_START, lmId);
	lmId = GetLmID(EOS_);
	m_sentenceEnd		= factorCollection.AddFactor(Output, m_factorType, SENTENCE_END, lmId);

}

LmId LanguageModel_IRST::GetLmID( const std::string &str ) const
{
    LanguageModel_IRST *lm = const_cast<LanguageModel_IRST*>(this); // hack. not sure if supposed to cast this
    LmId res;
    res.sri = lm->m_lmtb->dict->encode( str.c_str() );
    return res;
}

float LanguageModel_IRST::GetValue(const vector<const Factor*> &contextFactor) const
{
	// set up context
	size_t count = contextFactor.size();
  ngram ng(m_lmtb->dict);
	for (size_t i = 0 ; i < count ; i++)
	{
#ifdef CDYER_DEBUG_LMSCORE
		std::cout << i <<"="<<contextFactor[i]->GetLmId().irst <<"," << contextFactor[i]->GetString()<<" ";
#endif
		ng.pushc(contextFactor[i]->GetLmId().irst);
	}
#ifdef CDYER_DEBUG_LMSCORE
	std::cout <<" (ng='" << ng << "')\n";
#endif
	return TransformScore(m_lmtb->prob(ng));
}

<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>
#include <wiringPi.h>

#include <boost/lockfree/spsc_queue.hpp>

#include "../parser.hpp"

#define PIN_READ 27
#define PARSER_WAIT 200

#define ONE_BIT_LENGTH 200
#define MIN_SIGNAL_LENGTH (ONE_BIT_LENGTH / 2)

typedef int64_t duration_t;

struct Interrupt {
  std::chrono::high_resolution_clock::time_point timestamp;
  unsigned long long int duration;
  duration_t value;
};

typedef Interrupt *interrupt_t;
typedef boost::lockfree::spsc_queue<interrupt_t, boost::lockfree::capacity<500>> interrupt_list_t;

/*
 * interrupt_list_t is threadsafe as long as only one thread reads and only one
 * thread writes.
 */

// interrupt_list_t where our interrupt thread writes and main thread reads
interrupt_list_t interrupts;
// interrupt_list_t where our interrupt thread reads and main thread writes
interrupt_list_t empty;

void handleInterrupt(void) {
  interrupt_t interrupt;

  if (empty.read_available()) {
    interrupt = empty.front();
    empty.pop();
  } else {
    interrupt = new Interrupt();
  }

  interrupt->value = (unsigned int) (1 - ::digitalRead(PIN_READ));
  interrupt->timestamp = std::chrono::high_resolution_clock::now();

  if (!interrupts.push(interrupt)) {
    delete interrupt;
  }
}

void parse(void) {
  doorman::parser_t parser;
  interrupt_t current, previous;

  previous = new Interrupt();
  previous->value = 2; // doesn't exist
  previous->timestamp = std::chrono::high_resolution_clock::now();
  previous->duration = 0;

  while (true) {
    while (interrupts.read_available()) {
      current = interrupts.front();
      interrupts.pop();

      current->duration = std::chrono::duration_cast<std::chrono::microseconds>(
        current->timestamp - previous->timestamp
      ).count();

      if (current->duration < MIN_SIGNAL_LENGTH
          || current->value == previous->value) {
        previous->duration += current->duration;

        empty.push(current);
        continue;
      }

      unsigned int count = (unsigned int) round((1.0f * previous->duration) / ONE_BIT_LENGTH);

      if (count > 5) {
        count = 5;
      }

      while (count-- > 0) {
        if (parser.consume(previous->value)) {
          if (parser.is_ready()) {
            std::cout << '\n' << parser.bits[0] << parser.bits[1] << parser.bits[2] << parser.bits[2] <<
                parser.bits[4] << parser.bits[5] << parser.bits[6] << parser.bits[7] << parser.bits[8] << parser.bits[9] << parser.bits[10] << parser.bits[11] << std::endl;
            parser.reset();
          }
        } else {
          parser.reset();
        }
      }

      empty.push(previous);
      previous = current;
    }

    ::delayMicroseconds(PARSER_WAIT);
  }
}

int main(int argc, char ** argv) {
  ::wiringPiSetupGpio();
  ::pinMode(PIN_READ, INPUT);

  doorman::init();

  ::wiringPiISR(PIN_READ, INT_EDGE_BOTH, &handleInterrupt);

  parse();
}
<commit_msg>lower PARSER_WAIT<commit_after>#include <iostream>
#include <chrono>
#include <wiringPi.h>

#include <boost/lockfree/spsc_queue.hpp>

#include "../parser.hpp"

#define PIN_READ 27
#define PARSER_WAIT 20

#define ONE_BIT_LENGTH 200
#define MIN_SIGNAL_LENGTH (ONE_BIT_LENGTH / 2)

typedef int64_t duration_t;

struct Interrupt {
  std::chrono::high_resolution_clock::time_point timestamp;
  unsigned long long int duration;
  duration_t value;
};

typedef Interrupt *interrupt_t;
typedef boost::lockfree::spsc_queue<interrupt_t, boost::lockfree::capacity<500>> interrupt_list_t;

/*
 * interrupt_list_t is threadsafe as long as only one thread reads and only one
 * thread writes.
 */

// interrupt_list_t where our interrupt thread writes and main thread reads
interrupt_list_t interrupts;
// interrupt_list_t where our interrupt thread reads and main thread writes
interrupt_list_t empty;

void handleInterrupt(void) {
  interrupt_t interrupt;

  if (empty.read_available()) {
    interrupt = empty.front();
    empty.pop();
  } else {
    interrupt = new Interrupt();
  }

  interrupt->value = (unsigned int) (1 - ::digitalRead(PIN_READ));
  interrupt->timestamp = std::chrono::high_resolution_clock::now();

  if (!interrupts.push(interrupt)) {
    delete interrupt;
  }
}

void parse(void) {
  doorman::parser_t parser;
  interrupt_t current, previous;

  previous = new Interrupt();
  previous->value = 2; // doesn't exist
  previous->timestamp = std::chrono::high_resolution_clock::now();
  previous->duration = 0;

  while (true) {
    while (interrupts.read_available()) {
      current = interrupts.front();
      interrupts.pop();

      current->duration = std::chrono::duration_cast<std::chrono::microseconds>(
        current->timestamp - previous->timestamp
      ).count();

      if (current->duration < MIN_SIGNAL_LENGTH
          || current->value == previous->value) {
        previous->duration += current->duration;

        empty.push(current);
        continue;
      }

      unsigned int count = (unsigned int) round((1.0f * previous->duration) / ONE_BIT_LENGTH);

      if (count > 5) {
        count = 5;
      }

      while (count-- > 0) {
        if (parser.consume(previous->value)) {
          if (parser.is_ready()) {
            std::cout << '\n' << parser.bits[0] << parser.bits[1] << parser.bits[2] << parser.bits[2] <<
                parser.bits[4] << parser.bits[5] << parser.bits[6] << parser.bits[7] << parser.bits[8] << parser.bits[9] << parser.bits[10] << parser.bits[11] << std::endl;
            parser.reset();
          }
        } else {
          parser.reset();
        }
      }

      empty.push(previous);
      previous = current;
    }

    ::delayMicroseconds(PARSER_WAIT);
  }
}

int main(int argc, char ** argv) {
  ::wiringPiSetupGpio();
  ::pinMode(PIN_READ, INPUT);

  doorman::init();

  ::wiringPiISR(PIN_READ, INT_EDGE_BOTH, &handleInterrupt);

  parse();
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "packager/media/base/demuxer.h"

#include "packager/base/bind.h"
#include "packager/base/logging.h"
#include "packager/base/stl_util.h"
#include "packager/media/base/container_names.h"
#include "packager/media/base/decryptor_source.h"
#include "packager/media/base/key_source.h"
#include "packager/media/base/media_sample.h"
#include "packager/media/base/media_stream.h"
#include "packager/media/base/stream_info.h"
#include "packager/media/file/file.h"
#include "packager/media/formats/mp2t/mp2t_media_parser.h"
#include "packager/media/formats/mp4/mp4_media_parser.h"
#include "packager/media/formats/wvm/wvm_media_parser.h"

namespace {
const size_t kInitBufSize = 0x10000;  // 65KB, sufficient to determine the
                                      // container and likely all init data.
const size_t kBufSize = 0x200000;     // 2MB
}

namespace edash_packager {
namespace media {

Demuxer::Demuxer(const std::string& file_name)
    : file_name_(file_name),
      media_file_(NULL),
      init_event_received_(false),
      buffer_(new uint8_t[kBufSize]),
      cancelled_(false) {
}

Demuxer::~Demuxer() {
  if (media_file_)
    media_file_->Close();
  STLDeleteElements(&streams_);
}

void Demuxer::SetKeySource(scoped_ptr<KeySource> key_source) {
  key_source_ = key_source.Pass();
}

Status Demuxer::Initialize() {
  DCHECK(!media_file_);
  DCHECK(!init_event_received_);

  media_file_ = File::Open(file_name_.c_str(), "r");
  if (!media_file_) {
    return Status(error::FILE_FAILURE,
                  "Cannot open file for reading " + file_name_);
  }

  // Determine media container.
  int64_t bytes_read = media_file_->Read(buffer_.get(), kInitBufSize);
  if (bytes_read <= 0)
    return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
  MediaContainerName container = DetermineContainer(buffer_.get(), bytes_read);

  // Initialize media parser.
  switch (container) {
    case CONTAINER_MOV:
      parser_.reset(new mp4::MP4MediaParser());
      break;
    case CONTAINER_MPEG2TS:
      parser_.reset(new mp2t::Mp2tMediaParser());
      break;
    case CONTAINER_MPEG2PS:
      parser_.reset(new wvm::WvmMediaParser());
      break;
    default:
      NOTIMPLEMENTED();
      return Status(error::UNIMPLEMENTED, "Container not supported.");
  }

  parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
                base::Bind(&Demuxer::NewSampleEvent, base::Unretained(this)),
                key_source_.get());

  if (!parser_->Parse(buffer_.get(), bytes_read)) {
    init_parsing_status_ =
        Status(error::PARSER_FAILURE, "Cannot parse media file " + file_name_);
  }

  // Parse until init event received or on error.
  while (!init_event_received_ && init_parsing_status_.ok())
    init_parsing_status_ = Parse();
  // Defer error reporting if init completed successfully.
  return init_event_received_ ? Status::OK : init_parsing_status_;
}

void Demuxer::ParserInitEvent(
    const std::vector<scoped_refptr<StreamInfo> >& streams) {
  init_event_received_ = true;

  std::vector<scoped_refptr<StreamInfo> >::const_iterator it = streams.begin();
  for (; it != streams.end(); ++it) {
    streams_.push_back(new MediaStream(*it, this));
  }
}

bool Demuxer::NewSampleEvent(uint32_t track_id,
                             const scoped_refptr<MediaSample>& sample) {
  std::vector<MediaStream*>::iterator it = streams_.begin();
  for (; it != streams_.end(); ++it) {
    if (track_id == (*it)->info()->track_id()) {
      return (*it)->PushSample(sample).ok();
    }
  }
  return false;
}

Status Demuxer::Run() {
  Status status;

  // Start the streams.
  for (std::vector<MediaStream*>::iterator it = streams_.begin();
       it != streams_.end();
       ++it) {
    status = (*it)->Start(MediaStream::kPush);
    if (!status.ok())
      return status;
  }

  while (!cancelled_ && (status = Parse()).ok())
    continue;

  if (cancelled_ && status.ok())
    return Status(error::CANCELLED, "Demuxer run cancelled");

  if (status.error_code() == error::END_OF_STREAM) {
    // Push EOS sample to muxer to indicate end of stream.
    const scoped_refptr<MediaSample>& sample = MediaSample::CreateEOSBuffer();
    for (std::vector<MediaStream*>::iterator it = streams_.begin();
         it != streams_.end();
         ++it) {
      status = (*it)->PushSample(sample);
      if (!status.ok())
        return status;
    }
  }
  return status;
}

Status Demuxer::Parse() {
  DCHECK(media_file_);
  DCHECK(parser_);
  DCHECK(buffer_);

  // Return early and avoid call Parse(...) again if it has already failed at
  // the initialization.
  if (!init_parsing_status_.ok())
    return init_parsing_status_;

  int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
  if (bytes_read == 0) {
    parser_->Flush();
    return Status(error::END_OF_STREAM, "");
  } else if (bytes_read < 0) {
    return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
  }

  return parser_->Parse(buffer_.get(), bytes_read)
             ? Status::OK
             : Status(error::PARSER_FAILURE,
                      "Cannot parse media file " + file_name_);
}

void Demuxer::Cancel() {
  cancelled_ = true;
}

}  // namespace media
}  // namespace edash_packager
<commit_msg>Read enough bytes before detecting the container type<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "packager/media/base/demuxer.h"

#include "packager/base/bind.h"
#include "packager/base/logging.h"
#include "packager/base/stl_util.h"
#include "packager/media/base/container_names.h"
#include "packager/media/base/decryptor_source.h"
#include "packager/media/base/key_source.h"
#include "packager/media/base/media_sample.h"
#include "packager/media/base/media_stream.h"
#include "packager/media/base/stream_info.h"
#include "packager/media/file/file.h"
#include "packager/media/formats/mp2t/mp2t_media_parser.h"
#include "packager/media/formats/mp4/mp4_media_parser.h"
#include "packager/media/formats/wvm/wvm_media_parser.h"

namespace {
const size_t kInitBufSize = 0x10000;  // 65KB, sufficient to determine the
                                      // container and likely all init data.
const size_t kBufSize = 0x200000;     // 2MB
}

namespace edash_packager {
namespace media {

Demuxer::Demuxer(const std::string& file_name)
    : file_name_(file_name),
      media_file_(NULL),
      init_event_received_(false),
      buffer_(new uint8_t[kBufSize]),
      cancelled_(false) {
}

Demuxer::~Demuxer() {
  if (media_file_)
    media_file_->Close();
  STLDeleteElements(&streams_);
}

void Demuxer::SetKeySource(scoped_ptr<KeySource> key_source) {
  key_source_ = key_source.Pass();
}

Status Demuxer::Initialize() {
  DCHECK(!media_file_);
  DCHECK(!init_event_received_);

  media_file_ = File::Open(file_name_.c_str(), "r");
  if (!media_file_) {
    return Status(error::FILE_FAILURE,
                  "Cannot open file for reading " + file_name_);
  }

  // Read enough bytes before detecting the container.
  size_t bytes_read = 0;
  while (bytes_read < kInitBufSize) {
    int64_t read_result =
        media_file_->Read(buffer_.get() + bytes_read, kInitBufSize);
    if (read_result < 0)
      return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
    if (read_result == 0)
      break;
    bytes_read += read_result;
  }
  MediaContainerName container = DetermineContainer(buffer_.get(), bytes_read);

  // Initialize media parser.
  switch (container) {
    case CONTAINER_MOV:
      parser_.reset(new mp4::MP4MediaParser());
      break;
    case CONTAINER_MPEG2TS:
      parser_.reset(new mp2t::Mp2tMediaParser());
      break;
    case CONTAINER_MPEG2PS:
      parser_.reset(new wvm::WvmMediaParser());
      break;
    default:
      NOTIMPLEMENTED();
      return Status(error::UNIMPLEMENTED, "Container not supported.");
  }

  parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
                base::Bind(&Demuxer::NewSampleEvent, base::Unretained(this)),
                key_source_.get());

  if (!parser_->Parse(buffer_.get(), bytes_read)) {
    init_parsing_status_ =
        Status(error::PARSER_FAILURE, "Cannot parse media file " + file_name_);
  }

  // Parse until init event received or on error.
  while (!init_event_received_ && init_parsing_status_.ok())
    init_parsing_status_ = Parse();
  // Defer error reporting if init completed successfully.
  return init_event_received_ ? Status::OK : init_parsing_status_;
}

void Demuxer::ParserInitEvent(
    const std::vector<scoped_refptr<StreamInfo> >& streams) {
  init_event_received_ = true;

  std::vector<scoped_refptr<StreamInfo> >::const_iterator it = streams.begin();
  for (; it != streams.end(); ++it) {
    streams_.push_back(new MediaStream(*it, this));
  }
}

bool Demuxer::NewSampleEvent(uint32_t track_id,
                             const scoped_refptr<MediaSample>& sample) {
  std::vector<MediaStream*>::iterator it = streams_.begin();
  for (; it != streams_.end(); ++it) {
    if (track_id == (*it)->info()->track_id()) {
      return (*it)->PushSample(sample).ok();
    }
  }
  return false;
}

Status Demuxer::Run() {
  Status status;

  // Start the streams.
  for (std::vector<MediaStream*>::iterator it = streams_.begin();
       it != streams_.end();
       ++it) {
    status = (*it)->Start(MediaStream::kPush);
    if (!status.ok())
      return status;
  }

  while (!cancelled_ && (status = Parse()).ok())
    continue;

  if (cancelled_ && status.ok())
    return Status(error::CANCELLED, "Demuxer run cancelled");

  if (status.error_code() == error::END_OF_STREAM) {
    // Push EOS sample to muxer to indicate end of stream.
    const scoped_refptr<MediaSample>& sample = MediaSample::CreateEOSBuffer();
    for (std::vector<MediaStream*>::iterator it = streams_.begin();
         it != streams_.end();
         ++it) {
      status = (*it)->PushSample(sample);
      if (!status.ok())
        return status;
    }
  }
  return status;
}

Status Demuxer::Parse() {
  DCHECK(media_file_);
  DCHECK(parser_);
  DCHECK(buffer_);

  // Return early and avoid call Parse(...) again if it has already failed at
  // the initialization.
  if (!init_parsing_status_.ok())
    return init_parsing_status_;

  int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
  if (bytes_read == 0) {
    parser_->Flush();
    return Status(error::END_OF_STREAM, "");
  } else if (bytes_read < 0) {
    return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
  }

  return parser_->Parse(buffer_.get(), bytes_read)
             ? Status::OK
             : Status(error::PARSER_FAILURE,
                      "Cannot parse media file " + file_name_);
}

void Demuxer::Cancel() {
  cancelled_ = true;
}

}  // namespace media
}  // namespace edash_packager
<|endoftext|>


<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 <atlbase.h>
#include <atlcom.h>

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/http_negotiate.h"
#include "chrome_frame/html_utils.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/utils.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

class HttpNegotiateTest : public testing::Test {
 protected:
  HttpNegotiateTest() {
  }
};

class TestHttpNegotiate
    : public CComObjectRootEx<CComMultiThreadModel>,
      public IHttpNegotiate {
 public:
  TestHttpNegotiate()
      : beginning_transaction_ret_(S_OK), additional_headers_(NULL) {
  }

BEGIN_COM_MAP(TestHttpNegotiate)
  COM_INTERFACE_ENTRY(IHttpNegotiate)
END_COM_MAP()
  STDMETHOD(BeginningTransaction)(LPCWSTR url, LPCWSTR headers,  // NOLINT
                                  DWORD reserved,  // NOLINT
                                  LPWSTR* additional_headers) {  // NOLINT
    if (additional_headers_) {
      int len = lstrlenW(additional_headers_);
      len++;
      *additional_headers = reinterpret_cast<wchar_t*>(
          ::CoTaskMemAlloc(len * sizeof(wchar_t)));
      lstrcpyW(*additional_headers, additional_headers_);
    }
    return beginning_transaction_ret_;
  }

  STDMETHOD(OnResponse)(DWORD response_code, LPCWSTR response_header,
                        LPCWSTR request_header,
                        LPWSTR* additional_request_headers) {
    return S_OK;
  }

  HRESULT beginning_transaction_ret_;
  const wchar_t* additional_headers_;
};

TEST_F(HttpNegotiateTest, BeginningTransaction) {
  static const int kBeginningTransactionIndex = 3;
  CComObjectStackEx<TestHttpNegotiate> test_http;
  IHttpNegotiate_BeginningTransaction_Fn original =
      reinterpret_cast<IHttpNegotiate_BeginningTransaction_Fn>(
          (*reinterpret_cast<void***>(
              static_cast<IHttpNegotiate*>(
                  &test_http)))[kBeginningTransactionIndex]);

  std::wstring cf_ua(
      ASCIIToWide(http_utils::GetDefaultUserAgentHeaderWithCFTag()));
  std::wstring cf_tag(
      ASCIIToWide(http_utils::GetChromeFrameUserAgent()));

  EXPECT_NE(std::wstring::npos, cf_ua.find(cf_tag));

  struct TestCase {
    const std::wstring original_headers_;
    const std::wstring delegate_additional_;
    const std::wstring expected_additional_;
    HRESULT delegate_return_value_;
  } test_cases[] = {
    { L"Accept: */*\r\n",
      L"",
      cf_ua + L"\r\n",
      S_OK },
    { L"Accept: */*\r\n",
      L"",
      L"",
      E_OUTOFMEMORY },
    { L"",
      L"Accept: */*\r\n",
      L"Accept: */*\r\n" + cf_ua + L"\r\n",
      S_OK },
    { L"User-Agent: Bingo/1.0\r\n",
      L"",
      L"User-Agent: Bingo/1.0 " + cf_tag + L"\r\n",
      S_OK },
    { L"User-Agent: NotMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n",
      S_OK },
    { L"",
      L"User-Agent: MeMeMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n",
      S_OK },
  };

  for (int i = 0; i < arraysize(test_cases); ++i) {
    TestCase& test = test_cases[i];
    wchar_t* additional = NULL;
    test_http.beginning_transaction_ret_ = test.delegate_return_value_;
    test_http.additional_headers_ = test.delegate_additional_.c_str();
    HttpNegotiatePatch::BeginningTransaction(original, &test_http,
        L"http://www.google.com", test.original_headers_.c_str(), 0,
        &additional);
    EXPECT_TRUE(additional != NULL);

    if (additional) {
      // Check against the expected additional headers.
      EXPECT_EQ(test.expected_additional_, std::wstring(additional));
      ::CoTaskMemFree(additional);
    }
  }
}

class TestInternetProtocolSink
    : public CComObjectRootEx<CComMultiThreadModel>,
      public IInternetProtocolSink {
 public:
  TestInternetProtocolSink() : status_(0) {
    // Create an instance of IE to fullfill the requirements of being able
    // to detect whether a sub-frame or top-frame is being loaded (see
    // IsSubFrameRequest) and to be able to mark an IBrowserService
    // implementation as a target for CF navigation.
    HRESULT hr = browser_.CreateInstance(CLSID_InternetExplorer);
    CHECK(SUCCEEDED(hr));
    if (SUCCEEDED(hr)) {
      browser_->Navigate(base::win::ScopedBstr(L"about:blank"),
                         NULL, NULL, NULL, NULL);
    }
  }

  ~TestInternetProtocolSink() {
    if (browser_)
      browser_->Quit();
  }

BEGIN_COM_MAP(TestInternetProtocolSink)
  COM_INTERFACE_ENTRY(IInternetProtocolSink)
  COM_INTERFACE_ENTRY_AGGREGATE(IID_IServiceProvider, browser_)
END_COM_MAP()

  // IInternetProtocolSink.
  STDMETHOD(Switch)(PROTOCOLDATA* data) {
    NOTREACHED();
    return S_OK;
  }

  STDMETHOD(ReportProgress)(ULONG status, LPCWSTR text) {
    status_ = status;
    status_text_ = text ? text : L"";
    return S_OK;
  }

  STDMETHOD(ReportData)(DWORD bscf, ULONG progress, ULONG progress_max) {
    NOTREACHED();
    return S_OK;
  }

  STDMETHOD(ReportResult)(HRESULT hr, DWORD err, LPCWSTR result) {
    NOTREACHED();
    return S_OK;
  }

  ULONG last_status() const {
    return status_;
  }

  const std::wstring& last_status_text() const {
    return status_text_;
  }

 protected:
  ULONG status_;
  std::wstring status_text_;
  base::win::ScopedComPtr<IWebBrowser2> browser_;
};

using testing::AllOf;
using testing::ContainsRegex;
using testing::HasSubstr;

TEST(AppendUserAgent, Append) {
  EXPECT_THAT(AppendCFUserAgentString(NULL, NULL),
      testing::ContainsRegex("User-Agent:.+chromeframe.+\r\n"));

  // Check Http headers are reasonably parsed.
  EXPECT_THAT(AppendCFUserAgentString(L"Bad User-Agent: Age Tuners;\r\n", NULL),
      AllOf(ContainsRegex("User-Agent:.+chromeframe.+\r\n"),
            testing::Not(testing::HasSubstr("Age Tuners"))));

  // Honor headers User-Agent, if additional headers does not specify one.
  EXPECT_THAT(AppendCFUserAgentString(L"User-Agent: A Tense Rug;\r\n", NULL),
      ContainsRegex("User-Agent: A Tense Rug; chromeframe.+\r\n"));

  // Honor additional headers User-Agent.
  EXPECT_THAT(AppendCFUserAgentString(L"User-Agent: Near Guest;\r\n",
                                      L"User-Agent: Rat see Gun;\r\n"),
      ContainsRegex("User-Agent: Rat see Gun; chromeframe.+\r\n"));

  // Check additional headers are preserved.
  EXPECT_THAT(AppendCFUserAgentString(NULL,
            L"Authorization: A Zoo That I Ruin\r\n"
            L"User-Agent: Get a Nurse;\r\n"
            L"Accept-Language: Cleanup a Cat Egg\r\n"),
      AllOf(ContainsRegex("User-Agent: Get a Nurse; chromeframe.+\r\n"),
            HasSubstr("Authorization: A Zoo That I Ruin\r\n"),
            HasSubstr("Accept-Language: Cleanup a Cat Egg\r\n")));
}
<commit_msg>Fix the ChromeFrame BeginningTransaction unit test failures which validate the HttpNegotiate patch. On IE6/7/8 the chrome frame user agent is added to the ua section in the registry. This causes the test matcher to fail as the actual UA string contains the string chromeframe followed by the version of the dll.<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 <atlbase.h>
#include <atlcom.h>

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/http_negotiate.h"
#include "chrome_frame/html_utils.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/utils.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

class HttpNegotiateTest : public testing::Test {
 protected:
  HttpNegotiateTest() {
  }
};

class TestHttpNegotiate
    : public CComObjectRootEx<CComMultiThreadModel>,
      public IHttpNegotiate {
 public:
  TestHttpNegotiate()
      : beginning_transaction_ret_(S_OK), additional_headers_(NULL) {
  }

BEGIN_COM_MAP(TestHttpNegotiate)
  COM_INTERFACE_ENTRY(IHttpNegotiate)
END_COM_MAP()
  STDMETHOD(BeginningTransaction)(LPCWSTR url, LPCWSTR headers,  // NOLINT
                                  DWORD reserved,  // NOLINT
                                  LPWSTR* additional_headers) {  // NOLINT
    if (additional_headers_) {
      int len = lstrlenW(additional_headers_);
      len++;
      *additional_headers = reinterpret_cast<wchar_t*>(
          ::CoTaskMemAlloc(len * sizeof(wchar_t)));
      lstrcpyW(*additional_headers, additional_headers_);
    }
    return beginning_transaction_ret_;
  }

  STDMETHOD(OnResponse)(DWORD response_code, LPCWSTR response_header,
                        LPCWSTR request_header,
                        LPWSTR* additional_request_headers) {
    return S_OK;
  }

  HRESULT beginning_transaction_ret_;
  const wchar_t* additional_headers_;
};

TEST_F(HttpNegotiateTest, BeginningTransaction) {
  static const int kBeginningTransactionIndex = 3;
  CComObjectStackEx<TestHttpNegotiate> test_http;
  IHttpNegotiate_BeginningTransaction_Fn original =
      reinterpret_cast<IHttpNegotiate_BeginningTransaction_Fn>(
          (*reinterpret_cast<void***>(
              static_cast<IHttpNegotiate*>(
                  &test_http)))[kBeginningTransactionIndex]);

  std::wstring cf_ua(
      ASCIIToWide(http_utils::GetDefaultUserAgentHeaderWithCFTag()));
  std::wstring cf_tag(
      ASCIIToWide(http_utils::GetChromeFrameUserAgent()));

  EXPECT_NE(std::wstring::npos, cf_ua.find(L"chromeframe/"));

  struct TestCase {
    const std::wstring original_headers_;
    const std::wstring delegate_additional_;
    const std::wstring expected_additional_;
    HRESULT delegate_return_value_;
  } test_cases[] = {
    { L"Accept: */*\r\n",
      L"",
      cf_ua + L"\r\n",
      S_OK },
    { L"Accept: */*\r\n",
      L"",
      L"",
      E_OUTOFMEMORY },
    { L"",
      L"Accept: */*\r\n",
      L"Accept: */*\r\n" + cf_ua + L"\r\n",
      S_OK },
    { L"User-Agent: Bingo/1.0\r\n",
      L"",
      L"User-Agent: Bingo/1.0 " + cf_tag + L"\r\n",
      S_OK },
    { L"User-Agent: NotMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n",
      S_OK },
    { L"",
      L"User-Agent: MeMeMe/1.0\r\n",
      L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n",
      S_OK },
  };

  for (int i = 0; i < arraysize(test_cases); ++i) {
    TestCase& test = test_cases[i];
    wchar_t* additional = NULL;
    test_http.beginning_transaction_ret_ = test.delegate_return_value_;
    test_http.additional_headers_ = test.delegate_additional_.c_str();
    HttpNegotiatePatch::BeginningTransaction(original, &test_http,
        L"http://www.google.com", test.original_headers_.c_str(), 0,
        &additional);
    EXPECT_TRUE(additional != NULL);

    if (additional) {
      // Check against the expected additional headers.
      EXPECT_EQ(test.expected_additional_, std::wstring(additional));
      ::CoTaskMemFree(additional);
    }
  }
}

class TestInternetProtocolSink
    : public CComObjectRootEx<CComMultiThreadModel>,
      public IInternetProtocolSink {
 public:
  TestInternetProtocolSink() : status_(0) {
    // Create an instance of IE to fullfill the requirements of being able
    // to detect whether a sub-frame or top-frame is being loaded (see
    // IsSubFrameRequest) and to be able to mark an IBrowserService
    // implementation as a target for CF navigation.
    HRESULT hr = browser_.CreateInstance(CLSID_InternetExplorer);
    CHECK(SUCCEEDED(hr));
    if (SUCCEEDED(hr)) {
      browser_->Navigate(base::win::ScopedBstr(L"about:blank"),
                         NULL, NULL, NULL, NULL);
    }
  }

  ~TestInternetProtocolSink() {
    if (browser_)
      browser_->Quit();
  }

BEGIN_COM_MAP(TestInternetProtocolSink)
  COM_INTERFACE_ENTRY(IInternetProtocolSink)
  COM_INTERFACE_ENTRY_AGGREGATE(IID_IServiceProvider, browser_)
END_COM_MAP()

  // IInternetProtocolSink.
  STDMETHOD(Switch)(PROTOCOLDATA* data) {
    NOTREACHED();
    return S_OK;
  }

  STDMETHOD(ReportProgress)(ULONG status, LPCWSTR text) {
    status_ = status;
    status_text_ = text ? text : L"";
    return S_OK;
  }

  STDMETHOD(ReportData)(DWORD bscf, ULONG progress, ULONG progress_max) {
    NOTREACHED();
    return S_OK;
  }

  STDMETHOD(ReportResult)(HRESULT hr, DWORD err, LPCWSTR result) {
    NOTREACHED();
    return S_OK;
  }

  ULONG last_status() const {
    return status_;
  }

  const std::wstring& last_status_text() const {
    return status_text_;
  }

 protected:
  ULONG status_;
  std::wstring status_text_;
  base::win::ScopedComPtr<IWebBrowser2> browser_;
};

using testing::AllOf;
using testing::ContainsRegex;
using testing::HasSubstr;

TEST(AppendUserAgent, Append) {
  EXPECT_THAT(AppendCFUserAgentString(NULL, NULL),
      testing::ContainsRegex("User-Agent:.+chromeframe.+\r\n"));

  // Check Http headers are reasonably parsed.
  EXPECT_THAT(AppendCFUserAgentString(L"Bad User-Agent: Age Tuners;\r\n", NULL),
      AllOf(ContainsRegex("User-Agent:.+chromeframe.+\r\n"),
            testing::Not(testing::HasSubstr("Age Tuners"))));

  // Honor headers User-Agent, if additional headers does not specify one.
  EXPECT_THAT(AppendCFUserAgentString(L"User-Agent: A Tense Rug;\r\n", NULL),
      ContainsRegex("User-Agent: A Tense Rug; chromeframe.+\r\n"));

  // Honor additional headers User-Agent.
  EXPECT_THAT(AppendCFUserAgentString(L"User-Agent: Near Guest;\r\n",
                                      L"User-Agent: Rat see Gun;\r\n"),
      ContainsRegex("User-Agent: Rat see Gun; chromeframe.+\r\n"));

  // Check additional headers are preserved.
  EXPECT_THAT(AppendCFUserAgentString(NULL,
            L"Authorization: A Zoo That I Ruin\r\n"
            L"User-Agent: Get a Nurse;\r\n"
            L"Accept-Language: Cleanup a Cat Egg\r\n"),
      AllOf(ContainsRegex("User-Agent: Get a Nurse; chromeframe.+\r\n"),
            HasSubstr("Authorization: A Zoo That I Ruin\r\n"),
            HasSubstr("Accept-Language: Cleanup a Cat Egg\r\n")));
}
<|endoftext|>