<commit_before>#include "network_epoll.hpp"

#include "unistd.h"
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/eventfd.h>
#include <netinet/in.h>
#include <string.h>
#include <assert.h>

#include <iostream>
#include <fstream>
#include <sstream>

#define MAX_EVENTS 16

#ifdef USE_EDGE_TRIGGERED_EPOLL
#define MODE EPOLLET
#define READ while
#else
#define MODE 0
#define READ if
#endif

static void errno_exit(const char *s)
{
	std::ostringstream os;
	os << s << " error " << errno << ", " << strerror(errno);
	throw std::runtime_error(os.str());
}

NetworkThread::NetworkThread(Canvas& canvas, uint16_t port)
    : canvas(canvas)
{
	int fd_max;
	{
		std::ifstream fd_max_stream("/proc/sys/fs/file-max");
		if (!(fd_max_stream >> fd_max)) {
			throw std::runtime_error("Can not read /proc/sys/fs/file-max");
		}
	}
	state = new uint64_t[fd_max + 1];

	epollfd = epoll_create1(0);
	if (epollfd == -1)
		errno_exit("epoll_create1");

	evfd = eventfd(0, SOCK_NONBLOCK);
	struct epoll_event evee = { .events = EPOLLIN, .data = { .fd = evfd } };
	epoll_ctl(epollfd, EPOLL_CTL_ADD, evfd, &evee);

	struct sockaddr_in6 destAddr = {};
	destAddr.sin6_family = AF_INET6;
	destAddr.sin6_port = htons(port);
	serverfd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

	int one = 1;
	setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);

	if (serverfd == -1)
		errno_exit("socket");

	int err;

	err = bind(serverfd, (sockaddr*)&destAddr, sizeof(destAddr));
	if (err < 0)
		errno_exit("bind");

	err = listen(serverfd, 1);
	if (err < 0)
		errno_exit("listen");

	struct epoll_event serveree = { .events = EPOLLIN | MODE, .data = { .fd = serverfd } };
	epoll_ctl(epollfd, EPOLL_CTL_ADD, serverfd, &serveree);

	thread = std::thread(&NetworkThread::work, this);
}

NetworkThread::~NetworkThread()
{
	uint64_t one = 1;
	write(evfd, &one, sizeof one);
	thread.join();
	uint64_t devnull;
	read(evfd, &devnull, sizeof devnull);
	delete[] state;
}

void NetworkThread::work()
{
	const unsigned xmax = canvas.width, ymax = canvas.height;

	for (;;) {
		struct epoll_event event[MAX_EVENTS];
		int eventCnt = epoll_wait(epollfd, event, MAX_EVENTS, -1);
		for (int i = 0; i < eventCnt; i++) {
			int fd = event[i].data.fd;

			if (fd == evfd) {
				return;
			} else if (fd == serverfd) {
				int clientfd;
				READ ((clientfd = accept4(serverfd, nullptr, nullptr, SOCK_NONBLOCK)) >= 0) {
					state[clientfd] = 0;
					struct epoll_event ee = { .events = EPOLLIN | MODE, .data = { .fd = clientfd } };
					epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ee);
				}
			} else {
				char buf[32768];
				int size;
				READ ((size = read(fd, &buf, sizeof buf - 1)) > 0) {
					buf[size] = '\0';
					char* c = buf;
					uint64_t ss = state[fd];
					unsigned col = (ss >> 0) & 0xFFFFFFFF;
					unsigned x = (ss >> 32) & 0x1FFF;
					unsigned y = (ss >> 45) & 0x1FFF;
					unsigned comb = (ss >> 58) & 0x3F;
					unsigned s = comb / 9;
					unsigned dc = comb % 9;
					switch (s) {
						for (;;) {
						    case 0:
								if (*c == 'P') c++; else { s = 0; break; }
							case 1:
								if (*c == 'X') c++; else { s = 1; break; }
							case 2:
								if (*c == ' ') c++; else { s = 2; break; }
							case 3:
								while (*c >= '0' && *c <= '9' && dc < 4) {
									x = 10 * x + (*c - '0');
									if (x >= xmax)
										break;
									dc++;
									c++;
								}
								if (dc && *c == ' ') { dc = 0; c++; } else { s = 3; break; }
							case 4:
								while (*c >= '0' && *c <= '9' && dc < 4) {
									y = 10 * y + (*c - '0');
									if (y >= ymax)
										break;
									dc++;
									c++;
								}
								if (dc && *c == ' ') { dc = 0; c++; } else { s = 4; break; }
							case 5:
								s = 5;
								while (dc < 8) {
									if (*c >= '0' && *c <= '9') {
										col = (col << 4) | (*c - '0');
										dc++;
										c++;
									} else if (*c >= 'a' && *c <= 'f') {
										col = (col << 4) | (*c - 'a' + 0xA);
										dc++;
										c++;
									} else if (*c >= 'A' && *c <= 'F') {
										col = (col << 4) | (*c - 'A' + 0xA);
										dc++;
										c++;
									} else {
										break;
									}
								}
								if (*c == '\r') {
									c++;
									s = 6;
								}
							case 6:
								if (*c == '\n' && (dc == 6 || dc == 8)) {
									c++;
									if (dc == 6) {
										col <<= 8;
									}
									canvas.data[y * canvas.width + x] = col;
									s = x = y = col = dc = 0;
								} else {
									break;
								}
						}
					}
					if (c == buf + size) {
						state[fd] = ((col & 0xFFFFFFFFL) << 0) | ((x & 0x1FFFL) << 32) | ((y & 0x1FFFL) << 45) | (((s * 9 + dc) & 0x3FL) << 58);
					} else {
						close(fd);
					}
				}
				if (size == 0) {
					close(fd);
				}
			}
		}
	}
}
<commit_msg>Check return value of epoll_ctl<commit_after>#include "network_epoll.hpp"

#include "unistd.h"
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/eventfd.h>
#include <netinet/in.h>
#include <string.h>
#include <assert.h>

#include <iostream>
#include <fstream>
#include <sstream>

#define MAX_EVENTS 16

#ifdef USE_EDGE_TRIGGERED_EPOLL
#define MODE EPOLLET
#define READ while
#else
#define MODE 0
#define READ if
#endif

static void errno_exit(const char *s)
{
	std::ostringstream os;
	os << s << " error " << errno << ", " << strerror(errno);
	throw std::runtime_error(os.str());
}

NetworkThread::NetworkThread(Canvas& canvas, uint16_t port)
    : canvas(canvas)
{
	int fd_max;
	{
		std::ifstream fd_max_stream("/proc/sys/fs/file-max");
		if (!(fd_max_stream >> fd_max)) {
			throw std::runtime_error("Can not read /proc/sys/fs/file-max");
		}
	}
	state = new uint64_t[fd_max + 1];

	epollfd = epoll_create1(0);
	if (epollfd == -1)
		errno_exit("epoll_create1");

	evfd = eventfd(0, SOCK_NONBLOCK);
	struct epoll_event evee = { .events = EPOLLIN, .data = { .fd = evfd } };
	epoll_ctl(epollfd, EPOLL_CTL_ADD, evfd, &evee);

	struct sockaddr_in6 destAddr = {};
	destAddr.sin6_family = AF_INET6;
	destAddr.sin6_port = htons(port);
	serverfd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

	int one = 1;
	setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);

	if (serverfd == -1)
		errno_exit("socket");

	int err;

	err = bind(serverfd, (sockaddr*)&destAddr, sizeof(destAddr));
	if (err < 0)
		errno_exit("bind");

	err = listen(serverfd, 1);
	if (err < 0)
		errno_exit("listen");

	struct epoll_event serveree = { .events = EPOLLIN | MODE, .data = { .fd = serverfd } };
	err = epoll_ctl(epollfd, EPOLL_CTL_ADD, serverfd, &serveree);
	if (err < 0)
		errno_exit("epoll_ctl add server");

	thread = std::thread(&NetworkThread::work, this);
}

NetworkThread::~NetworkThread()
{
	uint64_t one = 1;
	write(evfd, &one, sizeof one);
	thread.join();
	uint64_t devnull;
	read(evfd, &devnull, sizeof devnull);
	delete[] state;
}

void NetworkThread::work()
{
	const unsigned xmax = canvas.width, ymax = canvas.height;

	for (;;) {
		struct epoll_event event[MAX_EVENTS];
		int eventCnt = epoll_wait(epollfd, event, MAX_EVENTS, -1);
		for (int i = 0; i < eventCnt; i++) {
			int fd = event[i].data.fd;

			if (fd == evfd) {
				return;
			} else if (fd == serverfd) {
				int clientfd;
				READ ((clientfd = accept4(serverfd, nullptr, nullptr, SOCK_NONBLOCK)) >= 0) {
					state[clientfd] = 0;
					struct epoll_event ee = { .events = EPOLLIN | MODE, .data = { .fd = clientfd } };
					int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ee);
					if (err < 0)
						errno_exit("epoll_ctl add client");
				}
			} else {
				char buf[32768];
				int size;
				READ ((size = read(fd, &buf, sizeof buf - 1)) > 0) {
					buf[size] = '\0';
					char* c = buf;
					uint64_t ss = state[fd];
					unsigned col = (ss >> 0) & 0xFFFFFFFF;
					unsigned x = (ss >> 32) & 0x1FFF;
					unsigned y = (ss >> 45) & 0x1FFF;
					unsigned comb = (ss >> 58) & 0x3F;
					unsigned s = comb / 9;
					unsigned dc = comb % 9;
					switch (s) {
						for (;;) {
						    case 0:
								if (*c == 'P') c++; else { s = 0; break; }
							case 1:
								if (*c == 'X') c++; else { s = 1; break; }
							case 2:
								if (*c == ' ') c++; else { s = 2; break; }
							case 3:
								while (*c >= '0' && *c <= '9' && dc < 4) {
									x = 10 * x + (*c - '0');
									if (x >= xmax)
										break;
									dc++;
									c++;
								}
								if (dc && *c == ' ') { dc = 0; c++; } else { s = 3; break; }
							case 4:
								while (*c >= '0' && *c <= '9' && dc < 4) {
									y = 10 * y + (*c - '0');
									if (y >= ymax)
										break;
									dc++;
									c++;
								}
								if (dc && *c == ' ') { dc = 0; c++; } else { s = 4; break; }
							case 5:
								s = 5;
								while (dc < 8) {
									if (*c >= '0' && *c <= '9') {
										col = (col << 4) | (*c - '0');
										dc++;
										c++;
									} else if (*c >= 'a' && *c <= 'f') {
										col = (col << 4) | (*c - 'a' + 0xA);
										dc++;
										c++;
									} else if (*c >= 'A' && *c <= 'F') {
										col = (col << 4) | (*c - 'A' + 0xA);
										dc++;
										c++;
									} else {
										break;
									}
								}
								if (*c == '\r') {
									c++;
									s = 6;
								}
							case 6:
								if (*c == '\n' && (dc == 6 || dc == 8)) {
									c++;
									if (dc == 6) {
										col <<= 8;
									}
									canvas.data[y * canvas.width + x] = col;
									s = x = y = col = dc = 0;
								} else {
									break;
								}
						}
					}
					if (c == buf + size) {
						state[fd] = ((col & 0xFFFFFFFFL) << 0) | ((x & 0x1FFFL) << 32) | ((y & 0x1FFFL) << 45) | (((s * 9 + dc) & 0x3FL) << 58);
					} else {
						close(fd);
					}
				}
				if (size == 0) {
					close(fd);
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>#if defined(LINUX)
#include "user/wqlinux.hh"
#elif defined(XV6_KERNEL)
#include "wqkernel.hh"
#else
#include "wquser.hh"
#endif
#include "percpu.hh"

#define NSLOTS (1 << WQSHIFT)

class wq {
public:
  wq();
  int push(work *w, int tcpuid);
  int trywork();
  void dump();

  static void* operator new(unsigned long);

private:
  work *steal(int c);
  work *pop(int c);
  void inclen(int c);
  void declen(int c);

  struct wqueue {
    work *w[NSLOTS];
    volatile int head __mpalign__;
    volatile int tail;
    wqlock_t lock;
  };

  struct stat {
    u64 push;
    u64 full;
    u64 pop;
    u64 steal;
  };

  percpu<wqueue> q_;
  percpu<stat> stat_;

#if defined(XV6_USER)
  uwq_ipcbuf* ipc_;
#endif
};

static wq *wq_;

size_t
wq_size(void)
{
  return sizeof(wq);
}

int
wq_push(work *w)
{
  return wq_->push(w, mycpuid());
}

int
wq_pushto(work *w, int tcpuid)
{
  return wq_->push(w, tcpuid);
}

int
wq_trywork(void)
{
  return wq_->trywork();
}

void
wq_dump(void)
{
  return wq_->dump();
}

void
initwq(void)
{
  wq_ = new wq();
  wqarch_init();
}

//
// wq
//
void*
wq::operator new(unsigned long nbytes)
{
  assert(nbytes == sizeof(wq));
  return allocwq(nbytes);
}

wq::wq(void)
{
  int i;

  for (i = 0; i < NCPU; i++)
    wqlock_init(&q_[i].lock);

#if defined(XV6_USER)
  ipc_ = allocipc();
  assert(wq_maxworkers <= NWORKERS);
  ipc_->maxworkers = wq_maxworkers;
#endif
}

void
wq::dump(void)
{
  int i;
  for (i = 0; i < NCPU; i++)
    xprintf("push %lu full %lu pop %lu steal %lu\n",
            stat_[i].push, stat_[i].full,
            stat_[i].pop, stat_[i].steal);
}

inline void
wq::inclen(int c)
{
#if defined(XV6_USER)
  __sync_fetch_and_add(&ipc_->len[c].v_, 1);
#endif
}

inline void
wq::declen(int c)
{
#if defined(XV6_USER)
  __sync_fetch_and_sub(&ipc_->len[c].v_, 1);
#endif
}

int
wq::push(work *w, int tcpuid)
{
  int i;

  acquire(&q_[tcpuid].lock);
  i = q_[tcpuid].head;
  if ((i - q_[tcpuid].tail) == NSLOTS) {
    stat_[tcpuid].full++;
    release(&q_[tcpuid].lock);
    return -1;
  }
  i = i & (NSLOTS-1);
  q_[tcpuid].w[i] = w;
  barrier();
  q_[tcpuid].head++;
  inclen(tcpuid);
  stat_[tcpuid].push++;
  release(&q_[tcpuid].lock);
  return 0;
}

inline work*
wq::pop(int c)
{
  struct wqueue *q = &q_[c];
  work *w;
  int i;

  i = q->head;
  if ((i - q->tail) == 0)
    return 0;

  wqlock_acquire(&q->lock);
  i = q->head;
  if ((i - q->tail) == 0) {
    wqlock_release(&q->lock);
    return 0;
  }
  i = (i-1) & (NSLOTS-1);
  w = q->w[i];
  q->head--;
  declen(c);
  wqlock_release(&q->lock);

  stat_->pop++;
  return w;
}

inline work*
wq::steal(int c)
{
  struct wqueue *q = &q_[c];
  work *w;
  int i;

  if (wqlock_tryacquire(&q->lock) == 0)
    return 0;
  i = q->tail;
  if ((i - q->head) == 0) {
    wqlock_release(&q->lock);
    return 0;
  }
  i = i & (NSLOTS-1);
  w = q->w[i];
  q->tail++;
  declen(c);
  wqlock_release(&q->lock);

  stat_->steal++;
  return w;
}

int
wq::trywork(void)
{
  work *w;
  u64 i, k;

  // A "random" victim CPU
  k = rdtsc();

  w = pop(mycpuid());
  if (w != nullptr) {
    w->run();
    return 1;
  }

  for (i = 0; i < NCPU; i++) {
    u64 j = (i+k) % NCPU;

    if (j == mycpuid())
        continue;

    w = steal(j);
    if (w != nullptr) {
      w->run();
      return 1;
    }
  }

  return 0;
}

//
// cwork
//
void
cwork::run(void)
{
  void (*fn)(void*, void*, void*, void*, void*) =
    (void(*)(void*,void*,void*,void*,void*))rip;
  fn(arg0, arg1, arg2, arg3, arg4);
  delete this;
}

void*
cwork::operator new(unsigned long nbytes)
{
  assert(nbytes == sizeof(cwork));
  return xallocwork(sizeof(cwork));
}

void*
cwork::operator new(unsigned long nbytes, cwork* buf)
{
  assert(nbytes == sizeof(cwork));
  return buf;
}

void
cwork::operator delete(void *p)
{
  xfreework(p, sizeof(cwork));
}
<commit_msg>flag to avoid stealing in the workqueue code, needed to ensure the exec-cleanup and wait-cleanup handlers run on the right core (disabled by default).<commit_after>#if defined(LINUX)
#include "user/wqlinux.hh"
#elif defined(XV6_KERNEL)
#include "wqkernel.hh"
#else
#include "wquser.hh"
#endif
#include "percpu.hh"

#define NSLOTS (1 << WQSHIFT)

enum { wq_steal_others = 1 };

class wq {
public:
  wq();
  int push(work *w, int tcpuid);
  int trywork();
  void dump();

  static void* operator new(unsigned long);

private:
  work *steal(int c);
  work *pop(int c);
  void inclen(int c);
  void declen(int c);

  struct wqueue {
    work *w[NSLOTS];
    volatile int head __mpalign__;
    volatile int tail;
    wqlock_t lock;
  };

  struct stat {
    u64 push;
    u64 full;
    u64 pop;
    u64 steal;
  };

  percpu<wqueue> q_;
  percpu<stat> stat_;

#if defined(XV6_USER)
  uwq_ipcbuf* ipc_;
#endif
};

static wq *wq_;

size_t
wq_size(void)
{
  return sizeof(wq);
}

int
wq_push(work *w)
{
  return wq_->push(w, mycpuid());
}

int
wq_pushto(work *w, int tcpuid)
{
  return wq_->push(w, tcpuid);
}

int
wq_trywork(void)
{
  return wq_->trywork();
}

void
wq_dump(void)
{
  return wq_->dump();
}

void
initwq(void)
{
  wq_ = new wq();
  wqarch_init();
}

//
// wq
//
void*
wq::operator new(unsigned long nbytes)
{
  assert(nbytes == sizeof(wq));
  return allocwq(nbytes);
}

wq::wq(void)
{
  int i;

  for (i = 0; i < NCPU; i++)
    wqlock_init(&q_[i].lock);

#if defined(XV6_USER)
  ipc_ = allocipc();
  assert(wq_maxworkers <= NWORKERS);
  ipc_->maxworkers = wq_maxworkers;
#endif
}

void
wq::dump(void)
{
  int i;
  for (i = 0; i < NCPU; i++)
    xprintf("push %lu full %lu pop %lu steal %lu\n",
            stat_[i].push, stat_[i].full,
            stat_[i].pop, stat_[i].steal);
}

inline void
wq::inclen(int c)
{
#if defined(XV6_USER)
  __sync_fetch_and_add(&ipc_->len[c].v_, 1);
#endif
}

inline void
wq::declen(int c)
{
#if defined(XV6_USER)
  __sync_fetch_and_sub(&ipc_->len[c].v_, 1);
#endif
}

int
wq::push(work *w, int tcpuid)
{
  int i;

  acquire(&q_[tcpuid].lock);
  i = q_[tcpuid].head;
  if ((i - q_[tcpuid].tail) == NSLOTS) {
    stat_[tcpuid].full++;
    release(&q_[tcpuid].lock);
    return -1;
  }
  i = i & (NSLOTS-1);
  q_[tcpuid].w[i] = w;
  barrier();
  q_[tcpuid].head++;
  inclen(tcpuid);
  stat_[tcpuid].push++;
  release(&q_[tcpuid].lock);
  return 0;
}

inline work*
wq::pop(int c)
{
  struct wqueue *q = &q_[c];
  work *w;
  int i;

  i = q->head;
  if ((i - q->tail) == 0)
    return 0;

  wqlock_acquire(&q->lock);
  i = q->head;
  if ((i - q->tail) == 0) {
    wqlock_release(&q->lock);
    return 0;
  }
  i = (i-1) & (NSLOTS-1);
  w = q->w[i];
  q->head--;
  declen(c);
  wqlock_release(&q->lock);

  stat_->pop++;
  return w;
}

inline work*
wq::steal(int c)
{
  if (!wq_steal_others && (c != mycpuid()))
    return 0;

  struct wqueue *q = &q_[c];
  work *w;
  int i;

  if (wqlock_tryacquire(&q->lock) == 0)
    return 0;
  i = q->tail;
  if ((i - q->head) == 0) {
    wqlock_release(&q->lock);
    return 0;
  }
  i = i & (NSLOTS-1);
  w = q->w[i];
  q->tail++;
  declen(c);
  wqlock_release(&q->lock);

  stat_->steal++;
  return w;
}

int
wq::trywork(void)
{
  work *w;
  u64 i, k;

  // A "random" victim CPU
  k = rdtsc();

  w = pop(mycpuid());
  if (w != nullptr) {
    w->run();
    return 1;
  }

  for (i = 0; i < NCPU; i++) {
    u64 j = (i+k) % NCPU;

    if (j == mycpuid())
        continue;

    w = steal(j);
    if (w != nullptr) {
      w->run();
      return 1;
    }
  }

  return 0;
}

//
// cwork
//
void
cwork::run(void)
{
  void (*fn)(void*, void*, void*, void*, void*) =
    (void(*)(void*,void*,void*,void*,void*))rip;
  fn(arg0, arg1, arg2, arg3, arg4);
  delete this;
}

void*
cwork::operator new(unsigned long nbytes)
{
  assert(nbytes == sizeof(cwork));
  return xallocwork(sizeof(cwork));
}

void*
cwork::operator new(unsigned long nbytes, cwork* buf)
{
  assert(nbytes == sizeof(cwork));
  return buf;
}

void
cwork::operator delete(void *p)
{
  xfreework(p, sizeof(cwork));
}
<|endoftext|>


<commit_before><commit_msg>Delete Worker.cpp<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/data/buffer_chain.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_BUFFER_CHAIN_HEADER
#define C7A_DATA_BUFFER_CHAIN_HEADER

#include <deque>
#include <condition_variable>
#include <mutex> //mutex, unique_lock

#include <c7a/data/binary_buffer.hpp>
#include <c7a/data/emitter_target.hpp>

namespace c7a {
namespace data {

//! Elements of a singly linked list, holding a immuteable buffer
struct BufferChainElement {
    BufferChainElement(BinaryBuffer b, size_t element_count, size_t offset = 0)
        : buffer(b),
        element_count(element_count),
        offset_of_first(offset) {
            //TODO(ts, sl) implement offset logic
            assert(offset_of_first == 0); //no support for offset right now
        }

    //! BinaryBuffer holds the data
    BinaryBuffer buffer;

    //! prefixsum of number of elements of previous BufferChainElements and
    //! this BufferChainElement
    size_t element_count;

    //! offset to the first element in the BinaryBuffer
    //! The cut-off element before that offset is not included in the element_count
    size_t offset_of_first;
};

using BufferChainIterator = std::deque<BufferChainElement>::const_iterator;

//! A Buffer chain holds multiple immuteable buffers.
//! Append in O(1), Delete in O(num_buffers)
struct BufferChain : public EmitterTarget {
    BufferChain() : closed_(false) { }

    //! Appends a BinaryBufferBuffer's content to the chain
    //! This method is thread-safe and runs in O(1)
    //! \Param b buffer to append
    void Append(BinaryBufferBuilder& b) {
        std::unique_lock<std::mutex> lock(append_mutex_);
        elements_.emplace_back(BufferChainElement(BinaryBuffer(b), size() + b.elements()));
        b.Detach();
        lock.unlock();
        NotifyWaitingThreads();
    }

    //! Waits until beeing notified
    void Wait() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.wait(lock);
    }

    //! Waits until beeing notified and closed == true
    void WaitUntilClosed() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.wait(lock, [=]() { return this->closed_; });
    }

    //! Call buffers' destructors and deconstructs the chain
    void Delete() {
        std::unique_lock<std::mutex> lock(append_mutex_);
        for (auto& elem : elements_)
            elem.buffer.Delete();
    }

    //! Returns the number of elements in this BufferChain at the current
    //! state.
    size_t size() {
        if (elements_.empty())
            return 0;
        return elements_.back().element_count;
    }

    BufferChainIterator Begin() {
        return elements_.begin();
    }

    BufferChainIterator End() {
        //TODO(ts) this should point to the last element in the buffer
        return elements_.end();
    }

    void Close() {
        closed_ = true;
        NotifyWaitingThreads();
    }

    bool IsClosed() { return closed_; }

    std::deque<BufferChainElement> elements_;

private:
    std::mutex                     mutex_;
    std::mutex                     append_mutex_;
    std::condition_variable        condition_variable_;
    bool                           closed_;

    void NotifyWaitingThreads() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.notify_all();
    }
};

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_BUFFER_CHAIN_HEADER

/******************************************************************************/
<commit_msg>remove false comment<commit_after>/*******************************************************************************
 * c7a/data/buffer_chain.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_BUFFER_CHAIN_HEADER
#define C7A_DATA_BUFFER_CHAIN_HEADER

#include <deque>
#include <condition_variable>
#include <mutex> //mutex, unique_lock

#include <c7a/data/binary_buffer.hpp>
#include <c7a/data/emitter_target.hpp>

namespace c7a {
namespace data {

//! Elements of a singly linked list, holding a immuteable buffer
struct BufferChainElement {
    BufferChainElement(BinaryBuffer b, size_t element_count, size_t offset = 0)
        : buffer(b),
        element_count(element_count),
        offset_of_first(offset) {
            //TODO(ts, sl) implement offset logic
            assert(offset_of_first == 0); //no support for offset right now
        }

    //! BinaryBuffer holds the data
    BinaryBuffer buffer;

    //! prefixsum of number of elements of previous BufferChainElements and
    //! this BufferChainElement
    size_t element_count;

    //! offset to the first element in the BinaryBuffer
    //! The cut-off element before that offset is not included in the element_count
    size_t offset_of_first;
};

using BufferChainIterator = std::deque<BufferChainElement>::const_iterator;

//! A Buffer chain holds multiple immuteable buffers.
//! Append in O(1), Delete in O(num_buffers)
struct BufferChain : public EmitterTarget {
    BufferChain() : closed_(false) { }

    //! Appends a BinaryBufferBuffer's content to the chain
    //! This method is thread-safe and runs in O(1)
    //! \Param b buffer to append
    void Append(BinaryBufferBuilder& b) {
        std::unique_lock<std::mutex> lock(append_mutex_);
        elements_.emplace_back(BufferChainElement(BinaryBuffer(b), size() + b.elements()));
        b.Detach();
        lock.unlock();
        NotifyWaitingThreads();
    }

    //! Waits until beeing notified
    void Wait() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.wait(lock);
    }

    //! Waits until beeing notified and closed == true
    void WaitUntilClosed() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.wait(lock, [=]() { return this->closed_; });
    }

    //! Call buffers' destructors and deconstructs the chain
    void Delete() {
        std::unique_lock<std::mutex> lock(append_mutex_);
        for (auto& elem : elements_)
            elem.buffer.Delete();
    }

    //! Returns the number of elements in this BufferChain at the current
    //! state.
    size_t size() {
        if (elements_.empty())
            return 0;
        return elements_.back().element_count;
    }

    BufferChainIterator Begin() {
        return elements_.begin();
    }

    BufferChainIterator End() {
        return elements_.end();
    }

    void Close() {
        closed_ = true;
        NotifyWaitingThreads();
    }

    bool IsClosed() { return closed_; }

    std::deque<BufferChainElement> elements_;

private:
    std::mutex                     mutex_;
    std::mutex                     append_mutex_;
    std::condition_variable        condition_variable_;
    bool                           closed_;

    void NotifyWaitingThreads() {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_variable_.notify_all();
    }
};

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_BUFFER_CHAIN_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "chrome/browser/browser_about_handler.h"

#include <algorithm>
#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/string_util.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"

namespace {

// Add paths here to be included in chrome://chrome-urls (about:about).
// These paths will also be suggested by BuiltinProvider.
const char* const kPaths[] = {
  chrome::kChromeUIAppCacheInternalsHost,
  chrome::kChromeUIBlobInternalsHost,
  chrome::kChromeUICacheHost,
  chrome::kChromeUIChromeURLsHost,
  chrome::kChromeUICrashesHost,
  chrome::kChromeUICreditsHost,
  chrome::kChromeUIDNSHost,
  chrome::kChromeUIGpuInternalsHost,
  chrome::kChromeUIHistoryHost,
  chrome::kChromeUIIPCHost,
  chrome::kChromeUIMediaInternalsHost,
  chrome::kChromeUIMemoryHost,
  chrome::kChromeUINetInternalsHost,
  chrome::kChromeUINetworkViewCacheHost,
  chrome::kChromeUINewTabHost,
  chrome::kChromeUIOmniboxHost,
  chrome::kChromeUIPredictorsHost,
  chrome::kChromeUIProfilerHost,
  chrome::kChromeUIQuotaInternalsHost,
  chrome::kChromeUIStatsHost,
  chrome::kChromeUISyncInternalsHost,
  chrome::kChromeUITermsHost,
  chrome::kChromeUIVersionHost,
#if defined(OS_ANDROID)
  chrome::kChromeUIWelcomeHost,
#else
  chrome::kChromeUIBookmarksHost,
  chrome::kChromeUIDownloadsHost,
  // TODO(dfalcantara): Enable after http://crbug.com/143146 is fixed.
  chrome::kChromeUIFlagsHost,
  chrome::kChromeUIFlashHost,
  chrome::kChromeUIInspectHost,
  chrome::kChromeUIPluginsHost,
  chrome::kChromeUISettingsHost,
  chrome::kChromeUITracingHost,
#endif
#if defined(OS_WIN)
  chrome::kChromeUIConflictsHost,
#endif
#if defined(OS_LINUX) || defined(OS_OPENBSD)
  chrome::kChromeUILinuxProxyConfigHost,
  chrome::kChromeUISandboxHost,
#endif
#if defined(OS_CHROMEOS)
  chrome::kChromeUIChooseMobileNetworkHost,
  chrome::kChromeUICryptohomeHost,
  chrome::kChromeUIDiagnosticsHost,
  chrome::kChromeUIDiscardsHost,
  chrome::kChromeUIDriveInternalsHost,
  chrome::kChromeUIImageBurnerHost,
  chrome::kChromeUIKeyboardOverlayHost,
  chrome::kChromeUILoginHost,
  chrome::kChromeUINetworkHost,
  chrome::kChromeUIOobeHost,
  chrome::kChromeUIOSCreditsHost,
  chrome::kChromeUIProxySettingsHost,
  chrome::kChromeUISystemInfoHost,
  chrome::kChromeUITaskManagerHost,
  chrome::kChromeUIWallpaperHost,
#endif
#if !defined(DISABLE_NACL)
  chrome::kChromeUINaClHost,
#endif
#if defined(ENABLE_CONFIGURATION_POLICY)
  chrome::kChromeUIPolicyHost,
#endif
#if defined(ENABLE_EXTENSIONS)
  chrome::kChromeUIExtensionsHost,
#endif
#if defined(ENABLE_PRINTING)
  chrome::kChromeUIPrintHost,
#endif
};

}  // namespace

bool WillHandleBrowserAboutURL(GURL* url,
                               content::BrowserContext* browser_context) {
  // TODO(msw): Eliminate "about:*" constants and literals from code and tests,
  //            then hopefully we can remove this forced fixup.
  *url = URLFixerUpper::FixupURL(url->possibly_invalid_spec(), std::string());

  // Check that about: URLs are fixed up to chrome: by URLFixerUpper::FixupURL.
  DCHECK((*url == GURL(chrome::kAboutBlankURL)) ||
         !url->SchemeIs(chrome::kAboutScheme));

  // Only handle chrome://foo/, URLFixerUpper::FixupURL translates about:foo.
  if (!url->SchemeIs(chrome::kChromeUIScheme))
    return false;

  std::string host(url->host());
  std::string path;
  // Replace about with chrome-urls.
  if (host == chrome::kChromeUIAboutHost)
    host = chrome::kChromeUIChromeURLsHost;
  // Replace cache with view-http-cache.
  if (host == chrome::kChromeUICacheHost) {
    host = chrome::kChromeUINetworkViewCacheHost;
  // Replace gpu with gpu-internals.
  } else if (host == chrome::kChromeUIGpuHost) {
    host = chrome::kChromeUIGpuInternalsHost;
  // Replace sync with sync-internals (for legacy reasons).
  } else if (host == chrome::kChromeUISyncHost) {
    host = chrome::kChromeUISyncInternalsHost;
  // Redirect chrome://extensions.
  } else if (host == chrome::kChromeUIExtensionsHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIExtensionsHost + url->path();
  // Redirect chrome://settings/extensions.
  // TODO(csilv): Remove this URL after M22 (legacy URL).
  } else if (host == chrome::kChromeUISettingsHost &&
      url->path() == std::string("/") + chrome::kExtensionsSubPage) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIExtensionsHost;
  // Redirect chrome://history.
  } else if (host == chrome::kChromeUIHistoryHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIHistoryHost + url->path();
  // Redirect chrome://settings
  } else if (host == chrome::kChromeUISettingsHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUISettingsHost + url->path();
  }
  GURL::Replacements replacements;
  replacements.SetHostStr(host);
  if (!path.empty())
    replacements.SetPathStr(path);
  *url = url->ReplaceComponents(replacements);

  // Having re-written the URL, make the chrome: handler process it.
  return false;
}

bool HandleNonNavigationAboutURL(const GURL& url) {
  std::string host(url.host());

  // chrome://ipc/ is currently buggy, so we disable it for official builds.
#if !defined(OFFICIAL_BUILD)

#if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
  if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) {
    // Run the dialog. This will re-use the existing one if it's already up.
    chrome::ShowAboutIPCDialog();
    return true;
  }
#endif

#endif  // OFFICIAL_BUILD

  return false;
}

std::vector<std::string> ChromePaths() {
  std::vector<std::string> paths(kPaths, kPaths + arraysize(kPaths));
  std::sort(paths.begin(), paths.end());
  return paths;
}
<commit_msg>Revert r158555 "[Android] Exclude unsupported URLs from chrome://chrome-urls."<commit_after>// Copyright (c) 2012 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 "chrome/browser/browser_about_handler.h"

#include <algorithm>
#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/string_util.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"

namespace {

// Add paths here to be included in chrome://chrome-urls (about:about).
// These paths will also be suggested by BuiltinProvider.
const char* const kPaths[] = {
  chrome::kChromeUIAppCacheInternalsHost,
  chrome::kChromeUIBlobInternalsHost,
  chrome::kChromeUIBookmarksHost,
  chrome::kChromeUICacheHost,
  chrome::kChromeUIChromeURLsHost,
  chrome::kChromeUICrashesHost,
  chrome::kChromeUICreditsHost,
  chrome::kChromeUIDNSHost,
  chrome::kChromeUIDownloadsHost,
  chrome::kChromeUIExtensionsHost,
  chrome::kChromeUIFlagsHost,
  chrome::kChromeUIFlashHost,
  chrome::kChromeUIGpuInternalsHost,
  chrome::kChromeUIHistoryHost,
  chrome::kChromeUIIPCHost,
  chrome::kChromeUIInspectHost,
  chrome::kChromeUIMediaInternalsHost,
  chrome::kChromeUIMemoryHost,
  chrome::kChromeUINaClHost,
  chrome::kChromeUINetInternalsHost,
  chrome::kChromeUINetworkViewCacheHost,
  chrome::kChromeUINewTabHost,
  chrome::kChromeUIOmniboxHost,
  chrome::kChromeUIPluginsHost,
  chrome::kChromeUIPolicyHost,
  chrome::kChromeUIPredictorsHost,
  chrome::kChromeUIProfilerHost,
  chrome::kChromeUIQuotaInternalsHost,
  chrome::kChromeUISettingsHost,
  chrome::kChromeUIStatsHost,
  chrome::kChromeUISyncInternalsHost,
#if defined(OS_CHROMEOS)
  chrome::kChromeUITaskManagerHost,
#endif
  chrome::kChromeUITermsHost,
  chrome::kChromeUITracingHost,
  chrome::kChromeUIVersionHost,
#if defined(OS_WIN)
  chrome::kChromeUIConflictsHost,
#endif
#if defined(OS_LINUX) || defined(OS_OPENBSD)
  chrome::kChromeUILinuxProxyConfigHost,
  chrome::kChromeUISandboxHost,
#endif
#if defined(OS_CHROMEOS)
  chrome::kChromeUIChooseMobileNetworkHost,
  chrome::kChromeUICryptohomeHost,
  chrome::kChromeUIDiagnosticsHost,
  chrome::kChromeUIDiscardsHost,
  chrome::kChromeUIDriveInternalsHost,
  chrome::kChromeUIImageBurnerHost,
  chrome::kChromeUIKeyboardOverlayHost,
  chrome::kChromeUILoginHost,
  chrome::kChromeUINetworkHost,
  chrome::kChromeUIOobeHost,
  chrome::kChromeUIOSCreditsHost,
  chrome::kChromeUIProxySettingsHost,
  chrome::kChromeUISystemInfoHost,
  chrome::kChromeUIWallpaperHost,
#endif
#if defined(ENABLE_PRINTING)
  chrome::kChromeUIPrintHost,
#endif
};

}  // namespace

bool WillHandleBrowserAboutURL(GURL* url,
                               content::BrowserContext* browser_context) {
  // TODO(msw): Eliminate "about:*" constants and literals from code and tests,
  //            then hopefully we can remove this forced fixup.
  *url = URLFixerUpper::FixupURL(url->possibly_invalid_spec(), std::string());

  // Check that about: URLs are fixed up to chrome: by URLFixerUpper::FixupURL.
  DCHECK((*url == GURL(chrome::kAboutBlankURL)) ||
         !url->SchemeIs(chrome::kAboutScheme));

  // Only handle chrome://foo/, URLFixerUpper::FixupURL translates about:foo.
  if (!url->SchemeIs(chrome::kChromeUIScheme))
    return false;

  std::string host(url->host());
  std::string path;
  // Replace about with chrome-urls.
  if (host == chrome::kChromeUIAboutHost)
    host = chrome::kChromeUIChromeURLsHost;
  // Replace cache with view-http-cache.
  if (host == chrome::kChromeUICacheHost) {
    host = chrome::kChromeUINetworkViewCacheHost;
  // Replace gpu with gpu-internals.
  } else if (host == chrome::kChromeUIGpuHost) {
    host = chrome::kChromeUIGpuInternalsHost;
  // Replace sync with sync-internals (for legacy reasons).
  } else if (host == chrome::kChromeUISyncHost) {
    host = chrome::kChromeUISyncInternalsHost;
  // Redirect chrome://extensions.
  } else if (host == chrome::kChromeUIExtensionsHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIExtensionsHost + url->path();
  // Redirect chrome://settings/extensions.
  // TODO(csilv): Remove this URL after M22 (legacy URL).
  } else if (host == chrome::kChromeUISettingsHost &&
      url->path() == std::string("/") + chrome::kExtensionsSubPage) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIExtensionsHost;
  // Redirect chrome://history.
  } else if (host == chrome::kChromeUIHistoryHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUIHistoryHost + url->path();
  // Redirect chrome://settings
  } else if (host == chrome::kChromeUISettingsHost) {
    host = chrome::kChromeUIUberHost;
    path = chrome::kChromeUISettingsHost + url->path();
  }
  GURL::Replacements replacements;
  replacements.SetHostStr(host);
  if (!path.empty())
    replacements.SetPathStr(path);
  *url = url->ReplaceComponents(replacements);

  // Having re-written the URL, make the chrome: handler process it.
  return false;
}

bool HandleNonNavigationAboutURL(const GURL& url) {
  std::string host(url.host());

  // chrome://ipc/ is currently buggy, so we disable it for official builds.
#if !defined(OFFICIAL_BUILD)

#if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
  if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) {
    // Run the dialog. This will re-use the existing one if it's already up.
    chrome::ShowAboutIPCDialog();
    return true;
  }
#endif

#endif  // OFFICIAL_BUILD

  return false;
}

std::vector<std::string> ChromePaths() {
  std::vector<std::string> paths(kPaths, kPaths + arraysize(kPaths));
  std::sort(paths.begin(), paths.end());
  return paths;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 "chrome/common/notification_registrar.h"

#include <algorithm>

#include "base/logging.h"
#include "chrome/common/notification_service.h"

struct NotificationRegistrar::Record {
  bool operator==(const Record& other) const;

  NotificationObserver* observer;
  NotificationType type;
  NotificationSource source;
};

bool NotificationRegistrar::Record::operator==(const Record& other) const {
  return observer == other.observer &&
         type == other.type &&
         source == other.source;
}

NotificationRegistrar::NotificationRegistrar() {
}

NotificationRegistrar::~NotificationRegistrar() {
  RemoveAll();
}

void NotificationRegistrar::Add(NotificationObserver* observer,
                                NotificationType type,
                                const NotificationSource& source) {
  Record record = { observer, type, source };
  DCHECK(std::find(registered_.begin(), registered_.end(), record) ==
         registered_.end()) << "Duplicate registration.";
  registered_.push_back(record);

  NotificationService::current()->AddObserver(observer, type, source);
}

void NotificationRegistrar::Remove(NotificationObserver* observer,
                                   NotificationType type,
                                   const NotificationSource& source) {
  Record record = { observer, type, source };
  RecordVector::iterator found = std::find(
      registered_.begin(), registered_.end(), record);
  if (found == registered_.end()) {
    NOTREACHED();
    return;
  }
  registered_.erase(found);

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service)
    service->RemoveObserver(observer, type, source);
}

void NotificationRegistrar::RemoveAll() {
  // Early-exit if no registrations, to avoid calling
  // NotificationService::current.  If we've constructed an object with a
  // NotificationRegistrar member, but haven't actually used the notification
  // service, and we reach prgram exit, then calling current() below could try
  // to initialize the service's lazy TLS pointer during exit, which throws
  // wrenches at things.
  if (registered_.empty())
    return;

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service) {
    for (size_t i = 0; i < registered_.size(); i++) {
      service->RemoveObserver(registered_[i].observer,
                              registered_[i].type,
                              registered_[i].source);
    }
  }
  registered_.clear();
}

bool NotificationRegistrar::IsEmpty() const {
  return registered_.empty();
}
<commit_msg>Add more logging on a NOTREACHED() in hopes of getting more data about why we're hitting it.<commit_after>// Copyright (c) 2006-2008 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 "chrome/common/notification_registrar.h"

#include <algorithm>

#include "base/logging.h"
#include "chrome/common/notification_service.h"

struct NotificationRegistrar::Record {
  bool operator==(const Record& other) const;

  NotificationObserver* observer;
  NotificationType type;
  NotificationSource source;
};

bool NotificationRegistrar::Record::operator==(const Record& other) const {
  return observer == other.observer &&
         type == other.type &&
         source == other.source;
}

NotificationRegistrar::NotificationRegistrar() {
}

NotificationRegistrar::~NotificationRegistrar() {
  RemoveAll();
}

void NotificationRegistrar::Add(NotificationObserver* observer,
                                NotificationType type,
                                const NotificationSource& source) {
  Record record = { observer, type, source };
  DCHECK(std::find(registered_.begin(), registered_.end(), record) ==
         registered_.end()) << "Duplicate registration.";
  registered_.push_back(record);

  NotificationService::current()->AddObserver(observer, type, source);
}

void NotificationRegistrar::Remove(NotificationObserver* observer,
                                   NotificationType type,
                                   const NotificationSource& source) {
  Record record = { observer, type, source };
  RecordVector::iterator found = std::find(
      registered_.begin(), registered_.end(), record);
  if (found == registered_.end()) {
    NOTREACHED() << "Trying to remove unregistered observer of type " <<
        type.value << " from list of size " << registered_.size() << ".";
    return;
  }
  registered_.erase(found);

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service)
    service->RemoveObserver(observer, type, source);
}

void NotificationRegistrar::RemoveAll() {
  // Early-exit if no registrations, to avoid calling
  // NotificationService::current.  If we've constructed an object with a
  // NotificationRegistrar member, but haven't actually used the notification
  // service, and we reach prgram exit, then calling current() below could try
  // to initialize the service's lazy TLS pointer during exit, which throws
  // wrenches at things.
  if (registered_.empty())
    return;

  // This can be NULL if our owner outlives the NotificationService, e.g. if our
  // owner is a Singleton.
  NotificationService* service = NotificationService::current();
  if (service) {
    for (size_t i = 0; i < registered_.size(); i++) {
      service->RemoveObserver(registered_[i].observer,
                              registered_[i].type,
                              registered_[i].source);
    }
  }
  registered_.clear();
}

bool NotificationRegistrar::IsEmpty() const {
  return registered_.empty();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

namespace {

const char* kPDFPluginName = "Chrome PDF Viewer";
const char* kPDFPluginMimeType = "application/pdf";
const char* kPDFPluginExtension = "pdf";
const char* kPDFPluginDescription = "Portable Document Format";

const char* kNaClPluginName = "Chrome NaCl";
const char* kNaClPluginMimeType = "application/x-nacl";
const char* kNaClPluginExtension = "nexe";
const char* kNaClPluginDescription = "Native Client Executable";

#if defined(ENABLE_REMOTING)
const char* kRemotingPluginMimeType = "pepper-application/x-chromoting";
#endif

// Appends the known built-in plugins to the given vector. Some built-in
// plugins are "internal" which means they are compiled into the Chrome binary,
// and some are extra shared libraries distributed with the browser (these are
// not marked internal, aside from being automatically registered, they're just
// regular plugins).
void ComputeBuiltInPlugins(std::vector<PepperPluginInfo>* plugins) {
  // PDF.
  //
  // Once we're sandboxed, we can't know if the PDF plugin is available or not;
  // but (on Linux) this function is always called once before we're sandboxed.
  // So the first time through test if the file is available and then skip the
  // check on subsequent calls if yes.
  static bool skip_pdf_file_check = false;
  FilePath path;
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
    if (skip_pdf_file_check || file_util::PathExists(path)) {
      PepperPluginInfo pdf;
      pdf.path = path;
      pdf.name = kPDFPluginName;
      pdf.mime_types.push_back(kPDFPluginMimeType);
      pdf.file_extensions = kPDFPluginExtension;
      pdf.type_descriptions = kPDFPluginDescription;
      plugins->push_back(pdf);

      skip_pdf_file_check = true;
    }
  }

  // Native client.
  //
  // Verify that we enable nacl on the command line. The name of the switch
  // varies between the browser and renderer process.
  if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path) &&
      file_util::PathExists(path)) {
    PepperPluginInfo nacl;
    nacl.path = path;
    nacl.name = kNaClPluginName;
    nacl.mime_types.push_back(kNaClPluginMimeType);

    // TODO(bbudge) Remove this mime type after NaCl tree has been updated.
    const char* kNaClPluginOldMimeType = "application/x-ppapi-nacl-srpc";
    nacl.mime_types.push_back(kNaClPluginOldMimeType);

    nacl.file_extensions = kNaClPluginExtension;
    nacl.type_descriptions = kNaClPluginDescription;
    plugins->push_back(nacl);
  }

  // Remoting.
#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableRemoting)) {
    PepperPluginInfo info;
    info.is_internal = true;
    info.path = FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back(kRemotingPluginMimeType);
    info.internal_entry_points.get_interface = remoting::PPP_GetInterface;
    info.internal_entry_points.initialize_module =
        remoting::PPP_InitializeModule;
    info.internal_entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugins->push_back(info);
  }
#endif
}

// Appends any plugins from the command line to the given vector.
void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
  const std::string value =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  bool out_of_process =
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::string> modules;
  base::SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::string> parts;
    base::SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::string> name_parts;
    base::SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.is_out_of_process = out_of_process;
#if defined(OS_WIN)
    // This means we can't provide plugins from non-ASCII paths, but
    // since this switch is only for development I don't think that's
    // too awful.
    plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
#else
    plugin.path = FilePath(name_parts[0]);
#endif
    if (name_parts.size() > 1)
      plugin.name = name_parts[1];
    if (name_parts.size() > 2) {
      plugin.description = name_parts[2];
      plugin.type_descriptions = name_parts[2];
    }
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(parts[j]);

    plugins->push_back(plugin);
  }
}

}  // namespace

const char* PepperPluginRegistry::kPDFPluginName = ::kPDFPluginName;

PepperPluginInfo::PepperPluginInfo()
    : is_internal(false),
      is_out_of_process(false) {
}

PepperPluginInfo::~PepperPluginInfo() {}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry* registry = NULL;
  // This object leaks.  It is a temporary hack to work around a crash.
  // http://code.google.com/p/chromium/issues/detail?id=63234
  if (!registry)
    registry = new PepperPluginRegistry;
  return registry;
}

// static
void PepperPluginRegistry::ComputeList(std::vector<PepperPluginInfo>* plugins) {
  ComputeBuiltInPlugins(plugins);
  ComputePluginsFromCommandLine(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  ComputeList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal && !plugins[i].is_out_of_process) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
    const FilePath& path) const {
  for (size_t i = 0; i < plugin_list_.size(); ++i) {
    if (path == plugin_list_[i].path)
      return &plugin_list_[i];
  }
  return NULL;
}

webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule(
    const FilePath& path) {
  NonOwningModuleMap::iterator it = live_modules_.find(path);
  if (it == live_modules_.end())
    return NULL;
  return it->second;
}

void PepperPluginRegistry::AddLiveModule(const FilePath& path,
                                         webkit::ppapi::PluginModule* module) {
  DCHECK(live_modules_.find(path) == live_modules_.end());
  live_modules_[path] = module;
}

void PepperPluginRegistry::PluginModuleDestroyed(
    webkit::ppapi::PluginModule* destroyed_module) {
  // Modules aren't destroyed very often and there are normally at most a
  // couple of them. So for now we just do a brute-force search.
  for (NonOwningModuleMap::iterator i = live_modules_.begin();
       i != live_modules_.end(); ++i) {
    if (i->second == destroyed_module) {
      live_modules_.erase(i);
      return;
    }
  }
  NOTREACHED();  // Should have always found the module above.
}

PepperPluginRegistry::~PepperPluginRegistry() {
  // Explicitly clear all preloaded modules first. This will cause callbacks
  // to erase these modules from the live_modules_ list, and we don't want
  // that to happen implicitly out-of-order.
  preloaded_modules_.clear();

  DCHECK(live_modules_.empty());
}

PepperPluginRegistry::PepperPluginRegistry() {
  ComputeList(&plugin_list_);

  // Note that in each case, AddLiveModule must be called before completing
  // initialization. If we bail out (in the continue clauses) before saving
  // the initialized module, it will still try to unregister itself in its
  // destructor.
  for (size_t i = 0; i < plugin_list_.size(); i++) {
    const PepperPluginInfo& current = plugin_list_[i];
    if (current.is_out_of_process)
      continue;  // Out of process plugins need no special pre-initialization.

    scoped_refptr<webkit::ppapi::PluginModule> module =
        new webkit::ppapi::PluginModule(current.name, this);
    AddLiveModule(current.path, module);
    if (current.is_internal) {
      if (!module->InitAsInternalPlugin(current.internal_entry_points)) {
        DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
        continue;
      }
    } else {
      // Preload all external plugins we're not running out of process.
      module = new webkit::ppapi::PluginModule(current.name, this);
      AddLiveModule(current.path, module);
      if (!module->InitAsLibrary(current.path)) {
        DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
        continue;
      }
    }
    preloaded_modules_[current.path] = module;
  }
}
<commit_msg>Remove double-initialization for plugin modules.<commit_after>// Copyright (c) 2011 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

namespace {

const char* kPDFPluginName = "Chrome PDF Viewer";
const char* kPDFPluginMimeType = "application/pdf";
const char* kPDFPluginExtension = "pdf";
const char* kPDFPluginDescription = "Portable Document Format";

const char* kNaClPluginName = "Chrome NaCl";
const char* kNaClPluginMimeType = "application/x-nacl";
const char* kNaClPluginExtension = "nexe";
const char* kNaClPluginDescription = "Native Client Executable";

#if defined(ENABLE_REMOTING)
const char* kRemotingPluginMimeType = "pepper-application/x-chromoting";
#endif

// Appends the known built-in plugins to the given vector. Some built-in
// plugins are "internal" which means they are compiled into the Chrome binary,
// and some are extra shared libraries distributed with the browser (these are
// not marked internal, aside from being automatically registered, they're just
// regular plugins).
void ComputeBuiltInPlugins(std::vector<PepperPluginInfo>* plugins) {
  // PDF.
  //
  // Once we're sandboxed, we can't know if the PDF plugin is available or not;
  // but (on Linux) this function is always called once before we're sandboxed.
  // So the first time through test if the file is available and then skip the
  // check on subsequent calls if yes.
  static bool skip_pdf_file_check = false;
  FilePath path;
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
    if (skip_pdf_file_check || file_util::PathExists(path)) {
      PepperPluginInfo pdf;
      pdf.path = path;
      pdf.name = kPDFPluginName;
      pdf.mime_types.push_back(kPDFPluginMimeType);
      pdf.file_extensions = kPDFPluginExtension;
      pdf.type_descriptions = kPDFPluginDescription;
      plugins->push_back(pdf);

      skip_pdf_file_check = true;
    }
  }

  // Native client.
  //
  // Verify that we enable nacl on the command line. The name of the switch
  // varies between the browser and renderer process.
  if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path) &&
      file_util::PathExists(path)) {
    PepperPluginInfo nacl;
    nacl.path = path;
    nacl.name = kNaClPluginName;
    nacl.mime_types.push_back(kNaClPluginMimeType);

    // TODO(bbudge) Remove this mime type after NaCl tree has been updated.
    const char* kNaClPluginOldMimeType = "application/x-ppapi-nacl-srpc";
    nacl.mime_types.push_back(kNaClPluginOldMimeType);

    nacl.file_extensions = kNaClPluginExtension;
    nacl.type_descriptions = kNaClPluginDescription;
    plugins->push_back(nacl);
  }

  // Remoting.
#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableRemoting)) {
    PepperPluginInfo info;
    info.is_internal = true;
    info.path = FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back(kRemotingPluginMimeType);
    info.internal_entry_points.get_interface = remoting::PPP_GetInterface;
    info.internal_entry_points.initialize_module =
        remoting::PPP_InitializeModule;
    info.internal_entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugins->push_back(info);
  }
#endif
}

// Appends any plugins from the command line to the given vector.
void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
  const std::string value =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  bool out_of_process =
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::string> modules;
  base::SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::string> parts;
    base::SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::string> name_parts;
    base::SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.is_out_of_process = out_of_process;
#if defined(OS_WIN)
    // This means we can't provide plugins from non-ASCII paths, but
    // since this switch is only for development I don't think that's
    // too awful.
    plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
#else
    plugin.path = FilePath(name_parts[0]);
#endif
    if (name_parts.size() > 1)
      plugin.name = name_parts[1];
    if (name_parts.size() > 2) {
      plugin.description = name_parts[2];
      plugin.type_descriptions = name_parts[2];
    }
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(parts[j]);

    plugins->push_back(plugin);
  }
}

}  // namespace

const char* PepperPluginRegistry::kPDFPluginName = ::kPDFPluginName;

PepperPluginInfo::PepperPluginInfo()
    : is_internal(false),
      is_out_of_process(false) {
}

PepperPluginInfo::~PepperPluginInfo() {}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry* registry = NULL;
  // This object leaks.  It is a temporary hack to work around a crash.
  // http://code.google.com/p/chromium/issues/detail?id=63234
  if (!registry)
    registry = new PepperPluginRegistry;
  return registry;
}

// static
void PepperPluginRegistry::ComputeList(std::vector<PepperPluginInfo>* plugins) {
  ComputeBuiltInPlugins(plugins);
  ComputePluginsFromCommandLine(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  ComputeList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal && !plugins[i].is_out_of_process) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
    const FilePath& path) const {
  for (size_t i = 0; i < plugin_list_.size(); ++i) {
    if (path == plugin_list_[i].path)
      return &plugin_list_[i];
  }
  return NULL;
}

webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule(
    const FilePath& path) {
  NonOwningModuleMap::iterator it = live_modules_.find(path);
  if (it == live_modules_.end())
    return NULL;
  return it->second;
}

void PepperPluginRegistry::AddLiveModule(const FilePath& path,
                                         webkit::ppapi::PluginModule* module) {
  DCHECK(live_modules_.find(path) == live_modules_.end());
  live_modules_[path] = module;
}

void PepperPluginRegistry::PluginModuleDestroyed(
    webkit::ppapi::PluginModule* destroyed_module) {
  // Modules aren't destroyed very often and there are normally at most a
  // couple of them. So for now we just do a brute-force search.
  for (NonOwningModuleMap::iterator i = live_modules_.begin();
       i != live_modules_.end(); ++i) {
    if (i->second == destroyed_module) {
      live_modules_.erase(i);
      return;
    }
  }
  NOTREACHED();  // Should have always found the module above.
}

PepperPluginRegistry::~PepperPluginRegistry() {
  // Explicitly clear all preloaded modules first. This will cause callbacks
  // to erase these modules from the live_modules_ list, and we don't want
  // that to happen implicitly out-of-order.
  preloaded_modules_.clear();

  DCHECK(live_modules_.empty());
}

PepperPluginRegistry::PepperPluginRegistry() {
  ComputeList(&plugin_list_);

  // Note that in each case, AddLiveModule must be called before completing
  // initialization. If we bail out (in the continue clauses) before saving
  // the initialized module, it will still try to unregister itself in its
  // destructor.
  for (size_t i = 0; i < plugin_list_.size(); i++) {
    const PepperPluginInfo& current = plugin_list_[i];
    if (current.is_out_of_process)
      continue;  // Out of process plugins need no special pre-initialization.

    scoped_refptr<webkit::ppapi::PluginModule> module =
        new webkit::ppapi::PluginModule(current.name, this);
    AddLiveModule(current.path, module);
    if (current.is_internal) {
      if (!module->InitAsInternalPlugin(current.internal_entry_points)) {
        DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
        continue;
      }
    } else {
      // Preload all external plugins we're not running out of process.
      if (!module->InitAsLibrary(current.path)) {
        DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
        continue;
      }
    }
    preloaded_modules_[current.path] = module;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/gfx/rect.h"
#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "views/controls/menu/chrome_menu.h"
#endif

class TabContents;

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

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

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

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}
#endif

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

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  // Pretend we processed them correctly.
  return true;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

bool FirstRun::CreateChromeDesktopShortcut() {
  NOTIMPLEMENTED();
  return false;
}

bool FirstRun::CreateChromeQuickLaunchShortcut() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

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

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
  virtual bool IsClosing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

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

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

#if !defined(TOOLKIT_VIEWS)
namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}
#endif

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

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
                                  bool* maximize_new_window) const {
  NOTIMPLEMENTED();
  return true;
}
#endif

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

#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
namespace views {

MenuItemView::MenuItemView(MenuDelegate* delegate) {
}

MenuItemView::~MenuItemView() {
}

MenuItemView* MenuItemView::AppendMenuItemInternal(int item_id,
                                                   const std::wstring& label,
                                                   const SkBitmap& icon,
                                                   Type type) {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::RunMenuAt(gfx::NativeView parent,
               const gfx::Rect& bounds,
               AnchorPosition anchor,
               bool has_mnemonics) {
  NOTIMPLEMENTED();
}

void MenuItemView::RunMenuForDropAt(gfx::NativeView parent,
                      const gfx::Rect& bounds,
                      AnchorPosition anchor) {
  NOTIMPLEMENTED();
}

// Hides and cancels the menu. This does nothing if the menu is not open.
void MenuItemView::Cancel() {
  NOTIMPLEMENTED();
}

SubmenuView* MenuItemView::CreateSubmenu() {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::SetSelected(bool selected) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon, int item_id) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon) {
  NOTIMPLEMENTED();
}

void MenuItemView::Paint(gfx::Canvas* canvas) {
  NOTIMPLEMENTED();
}

gfx::Size MenuItemView::GetPreferredSize() {
  NOTIMPLEMENTED();
  return gfx::Size();
}

MenuController* MenuItemView::GetMenuController() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuDelegate* MenuItemView::GetDelegate() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuItemView* MenuItemView::GetRootMenuItem() {
  NOTIMPLEMENTED();
  return NULL;
}

wchar_t MenuItemView::GetMnemonic() {
  return 'a';
}

}  // namespace views

#endif
<commit_msg>Hopefully fix the Linux build again. Review URL: http://codereview.chromium.org/115850<commit_after>// Copyright (c) 2009 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 "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/gfx/rect.h"
#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "views/controls/menu/chrome_menu.h"
#endif

class TabContents;

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

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

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

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}
#endif

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

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  // Pretend we processed them correctly.
  return true;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

bool FirstRun::CreateChromeDesktopShortcut() {
  NOTIMPLEMENTED();
  return false;
}

bool FirstRun::CreateChromeQuickLaunchShortcut() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

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

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
  virtual bool IsClosing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

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

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

#if !defined(TOOLKIT_VIEWS)
namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}
#endif

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

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif

#if defined(OS_MACOSX)
bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
                                  bool* maximize_new_window) const {
  NOTIMPLEMENTED();
  return true;
}
#endif

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

#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
namespace views {

MenuItemView::MenuItemView(MenuDelegate* delegate) {
}

MenuItemView::~MenuItemView() {
}

MenuItemView* MenuItemView::AppendMenuItemInternal(int item_id,
                                                   const std::wstring& label,
                                                   const SkBitmap& icon,
                                                   Type type) {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::RunMenuAt(gfx::NativeView parent,
               const gfx::Rect& bounds,
               AnchorPosition anchor,
               bool has_mnemonics) {
  NOTIMPLEMENTED();
}

void MenuItemView::RunMenuForDropAt(gfx::NativeView parent,
                      const gfx::Rect& bounds,
                      AnchorPosition anchor) {
  NOTIMPLEMENTED();
}

// Hides and cancels the menu. This does nothing if the menu is not open.
void MenuItemView::Cancel() {
  NOTIMPLEMENTED();
}

SubmenuView* MenuItemView::CreateSubmenu() {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::SetSelected(bool selected) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon, int item_id) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon) {
  NOTIMPLEMENTED();
}

void MenuItemView::Paint(gfx::Canvas* canvas) {
  NOTIMPLEMENTED();
}

gfx::Size MenuItemView::GetPreferredSize() {
  NOTIMPLEMENTED();
  return gfx::Size();
}

MenuController* MenuItemView::GetMenuController() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuDelegate* MenuItemView::GetDelegate() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuItemView* MenuItemView::GetRootMenuItem() {
  NOTIMPLEMENTED();
  return NULL;
}

wchar_t MenuItemView::GetMnemonic() {
  return 'a';
}

}  // namespace views

#endif
<|endoftext|>


<commit_before>/**
 * \file dcs/testbed/base_application.hpp
 *
 * \brief Base class for applications.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright (C) 2012       Marco Guazzone (marco.guazzone@gmail.com)
 *                          [Distributed Computing System (DCS) Group,
 *                           Computer Science Institute,
 *                           Department of Science and Technological Innovation,
 *                           University of Piemonte Orientale,
 *                           Alessandria (Italy)]
 *
 * This file is part of dcsxx-testbed (below referred to as "this program").
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DCS_TESTBED_BASE_APPLICATION_HPP
#define DCS_TESTBED_BASE_APPLICATION_HPP

#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <cstddef>
#include <dcs/testbed/application_performance_category.hpp>
#include <dcs/testbed/base_sensor.hpp>
#include <dcs/testbed/base_virtual_machine.hpp>

namespace dcs { namespace testbed {

template <typename TraitsT>
class base_application
{
	public: typedef TraitsT traits_type;
	public: typedef base_virtual_machine<traits_type> vm_type;
	public: typedef ::boost::shared_ptr<vm_type> vm_pointer;
	public: typedef base_sensor<traits_type> sensor_type;
	public: typedef ::boost::shared_ptr<sensor_type> sensor_pointer;
	public: typedef typename traits_type::real_type real_type;
	public: typedef ::boost::function<bool (real_type x)> slo_checker_type;

	public: virtual ~base_application()
	{
	}

	public: ::std::size_t num_vms() const
	{
		return do_num_vms();
	}

	public: ::std::vector<vm_pointer> vms() const
	{
		return do_vms();
	}

	public: void register_sensor(application_performance_category cat, sensor_pointer const& p_sens)
	{
		do_register_sensor(cat, p_sens);
	}

	public: void deregister_sensor(application_performance_category cat)
	{
		do_deregister_sensor(cat);
	}

	public: sensor_pointer sensor(application_performance_category cat)
	{
		return do_sensor(cat);
	}

	public: sensor_pointer sensor(application_performance_category cat) const
	{
		return do_sensor(cat);
	}

	public: template <typename FuncT>
			void slo(application_performance_category cat, FuncT checker)
	{
		do_slo(cat, slo_checker_type(checker));
	}

	public: bool slo(application_performance_category cat, real_type val)
	{
		return do_slo(cat, val);
	}

	private: virtual ::std::size_t do_num_vms() const = 0;

	private: virtual ::std::vector<vm_pointer> do_vms() const = 0;

	private: virtual void do_register_sensor(application_performance_category cat, sensor_pointer const& p_sens) = 0;

	private: virtual void do_deregister_sensor(application_performance_category cat) = 0;

	private: virtual sensor_pointer do_sensor(application_performance_category cat) = 0;

	private: virtual sensor_pointer do_sensor(application_performance_category cat) const = 0;

	private: virtual void do_slo(application_performance_category cat, slo_checker_type const& checker) = 0;

	private: virtual bool do_slo(application_performance_category cat, real_type val) const = 0;
}; // base_application

}} // Namespace dcs::testbed

#endif // DCS_TESTBED_BASE_APPLICATION_HPP
<commit_msg>(new:major) Added id management and name getter/setter<commit_after>/**
 * \file dcs/testbed/base_application.hpp
 *
 * \brief Base class for applications.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright (C) 2012       Marco Guazzone (marco.guazzone@gmail.com)
 *                          [Distributed Computing System (DCS) Group,
 *                           Computer Science Institute,
 *                           Department of Science and Technological Innovation,
 *                           University of Piemonte Orientale,
 *                           Alessandria (Italy)]
 *
 * This file is part of dcsxx-testbed (below referred to as "this program").
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DCS_TESTBED_BASE_APPLICATION_HPP
#define DCS_TESTBED_BASE_APPLICATION_HPP

#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <cstddef>
#include <dcs/testbed/application_performance_category.hpp>
#include <dcs/testbed/base_sensor.hpp>
#include <dcs/testbed/base_virtual_machine.hpp>
#include <string>

namespace dcs { namespace testbed {

template <typename TraitsT>
class base_application
{
	public: typedef TraitsT traits_type;
	public: typedef base_virtual_machine<traits_type> vm_type;
	public: typedef ::boost::shared_ptr<vm_type> vm_pointer;
//	public: typedef typename vm_type::identifier_type vm_identifier_type;
	public: typedef base_sensor<traits_type> sensor_type;
	public: typedef ::boost::shared_ptr<sensor_type> sensor_pointer;
	public: typedef typename traits_type::real_type real_type;
	public: typedef ::boost::function<bool (real_type x)> slo_checker_type;
	public: typedef unsigned long identifier_type;

	private: static identifier_type next_id_;

	public: static identifier_type make_id()
	{
		return next_id_++;
	}

	public: base_application()
	: id_(make_id())
	{
	}

	public: virtual ~base_application()
	{
	}

	public: identifier_type id() const
	{
		return id_;
	}

	public: void name(::std::string const& val)
	{
		name_ = val;
	}

	public: ::std::string name() const
	{
		return name_;
	}

	public: ::std::size_t num_vms() const
	{
		return do_num_vms();
	}

	public: ::std::vector<vm_pointer> vms() const
	{
		return do_vms();
	}

//	public: vm_pointer vm(vm_identifier_type id) const
//	{
//		return do_vm(id);
//	}

	public: void register_sensor(application_performance_category cat, sensor_pointer const& p_sens)
	{
		do_register_sensor(cat, p_sens);
	}

	public: void deregister_sensor(application_performance_category cat)
	{
		do_deregister_sensor(cat);
	}

	public: sensor_pointer sensor(application_performance_category cat)
	{
		return do_sensor(cat);
	}

	public: sensor_pointer sensor(application_performance_category cat) const
	{
		return do_sensor(cat);
	}

	public: template <typename FuncT>
			void slo(application_performance_category cat, FuncT checker)
	{
		do_slo(cat, slo_checker_type(checker));
	}

	public: bool slo(application_performance_category cat, real_type val)
	{
		return do_slo(cat, val);
	}

	private: virtual ::std::size_t do_num_vms() const = 0;

	private: virtual ::std::vector<vm_pointer> do_vms() const = 0;

	private: virtual void do_register_sensor(application_performance_category cat, sensor_pointer const& p_sens) = 0;

	private: virtual void do_deregister_sensor(application_performance_category cat) = 0;

	private: virtual sensor_pointer do_sensor(application_performance_category cat) = 0;

	private: virtual sensor_pointer do_sensor(application_performance_category cat) const = 0;

	private: virtual void do_slo(application_performance_category cat, slo_checker_type const& checker) = 0;

	private: virtual bool do_slo(application_performance_category cat, real_type val) const = 0;

	private: identifier_type id_; ///< The unique identifier
	private: ::std::string name_; ///< The mnemonic name of this application
}; // base_application

template <typename T>
typename base_application<T>::identifier_type base_application<T>::next_id_ = 0;

}} // Namespace dcs::testbed

#endif // DCS_TESTBED_BASE_APPLICATION_HPP
<|endoftext|>