Esempio n. 1
0
/* Return -1 error
 * Return 0 need to write again
 * Reutrn 1 all data was write
 */
int write_socks(s_socket *s, s_buffer *buf){
	int k;
#ifdef HAVE_LIBSSL
	if ( s->ssl != NULL ){
		k = SSL_write(s->ssl, buf->data + buf->a, buf_size(buf));
		if (k < 0){ perror("write socks"); return -1; }
		buf->a += k;
		return buf_empty(buf);
	}
#endif
	k = write(s->soc, buf->data + buf->a, buf_size(buf));
	if (k < 0){ perror("write socks"); return -1; }
	buf->a += k;
	return buf_empty(buf);
}
Esempio n. 2
0
char * jsonFetch(char *url)
{
    CURL *curl = curl_easy_init();
		buf_t *buf = buf_size(NULL, BUFFER_SIZE);
    
    curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, jsonFetchData);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf);
		curl_easy_setopt(curl, CURLOPT_USERAGENT, "vkp (https://github.com/pashashocky), pashashocky");
		
		struct curl_slist *hs = curl_slist_append(NULL, "Accept: application/json");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);

    CURLcode res = curl_easy_perform(curl);
		if (res != CURLE_OK)
			log_err("curl_easy_perform failed: %s", curl_easy_strerror(res));


    curl_easy_cleanup(curl);
    curl_slist_free_all(hs);

		char *js = buf_tostr(buf);
		free(buf->data);
		free(buf);

		/* printf("%s\n", js); */

    return js;
    
}
Esempio n. 3
0
char * json_fetch(char *url)
{
    CURL *curl = curl_easy_init();
    log_null(curl);

    curl_easy_setopt(curl, CURLOPT_URL, url);

    buf_t *buf = buf_size(NULL, BUFFER_SIZE);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fetch_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "jsmn-example (https://github.com/alisdair/jsmn-example, [email protected])");

    struct curl_slist *hs = curl_slist_append(NULL, "Accept: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
        log_die("curl_easy_perform failed: %s", curl_easy_strerror(res));

    curl_easy_cleanup(curl);
    curl_slist_free_all(hs);

    char *js = buf_tostr(buf);
    free(buf->data);
    free(buf);

    return js;
}
Esempio n. 4
0
scan_buffer::~scan_buffer()
{
  if (_buf) {
    _allocator->del_buffer(_buf, buf_size());
  }
  delete _allocator;
}
Esempio n. 5
0
const char *
host_port_to_string(const char *hostname, host_addr_t addr, uint16 port)
{
	buf_t *b = buf_private(G_STRFUNC, MAX_HOSTLEN + HOST_ADDR_PORT_BUFLEN);
	char *p = buf_data(b);

	if (hostname != NULL) {
		char port_buf[UINT32_DEC_BUFLEN];

		uint32_to_string_buf(port, port_buf, sizeof port_buf);
		concat_strings(p, buf_size(b), hostname, ":", port_buf, NULL_PTR);
	} else {
		host_addr_port_to_string_buf(addr, port, p, buf_size(b));
	}
	return p;
}
static void
bts_config_buffer(struct bts_buffer *buf)
{
	int cpu = raw_smp_processor_id();
	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
	struct bts_phys *phys = &buf->buf[buf->cur_buf];
	unsigned long index, thresh = 0, end = phys->size;
	struct page *page = phys->page;

	index = local_read(&buf->head);

	if (!buf->snapshot) {
		if (buf->end < phys->offset + buf_size(page))
			end = buf->end - phys->offset - phys->displacement;

		index -= phys->offset + phys->displacement;

		if (end - index > BTS_SAFETY_MARGIN)
			thresh = end - BTS_SAFETY_MARGIN;
		else if (end - index > BTS_RECORD_SIZE)
			thresh = end - BTS_RECORD_SIZE;
		else
			thresh = end;
	}

	ds->bts_buffer_base = (u64)(long)page_address(page) + phys->displacement;
	ds->bts_index = ds->bts_buffer_base + index;
	ds->bts_absolute_maximum = ds->bts_buffer_base + end;
	ds->bts_interrupt_threshold = !buf->snapshot
		? ds->bts_buffer_base + thresh
		: ds->bts_absolute_maximum + BTS_RECORD_SIZE;
}
Esempio n. 7
0
static void
http_callback(http_req_aux_t *req, void *opaque)
{
  char errbuf[128];
  tracker_torrent_t *tt = opaque;
  torrent_t *to = tt->tt_torrent;
  htsmsg_t *msg;
  net_addr_t na;

  assert(tt->tt_http_req != NULL);
  tt->tt_http_req = NULL;

  buf_t *b = http_req_get_result(req);

  tt->tt_interval = MIN(3600, tt->tt_interval * 2);

  if(b != NULL) {
    msg = bencode_deserialize(buf_cstr(b),
                              buf_cstr(b) + buf_size(b),
                              errbuf, sizeof(errbuf), NULL, NULL);
    if(msg != NULL) {

      const char *err = htsmsg_get_str(msg, "failure reason");
      if(err != NULL) {
        tracker_trace(tt->tt_tracker, "%s for %s", err, to->to_title);
        goto done;
      }

      const char *trackerid = htsmsg_get_str(msg, "trackerid");

      if(trackerid != NULL)
        mystrset(&tt->tt_trackerid, trackerid);

      tt->tt_interval =
        htsmsg_get_u32_or_default(msg, "min interval",
                                  htsmsg_get_u32_or_default(msg,
                                                            "interval", 1800));

      htsmsg_t *peers = htsmsg_get_list(msg, "peers");
      if(peers != NULL) {
        htsmsg_field_t *f;
        HTSMSG_FOREACH(f, peers) {
          htsmsg_t *sub = htsmsg_get_map_by_field(f);
          if(sub == NULL)
            continue;
          const char *ip = htsmsg_get_str(sub, "ip");
          if(ip == NULL)
            continue;

          if(net_resolve_numeric(ip, &na))
            continue;

          na.na_port = htsmsg_get_u32_or_default(sub, "port", 0);
          if(na.na_port == 0)
            continue;
          peer_add(to, &na);
        }
      }
Esempio n. 8
0
/**
 * Same as xnode_to_string().
 */
const char *
xnode_to_string2(const xnode_t *xn)
{
	buf_t *b = buf_private(G_STRFUNC, 256);
	char *p = buf_data(b);

	xnode_to_string_buf(xn, p, buf_size(b));
	return p;
}
Esempio n. 9
0
/**
 * @return the "address:port" string for a host
 */
const char *
gnet_host_to_string2(const gnet_host_t *h)
{
	buf_t *b = buf_private(G_STRFUNC, HOST_ADDR_PORT_BUFLEN);
	char *p = buf_data(b);

	gnet_host_to_string_buf(h, p, buf_size(b));
	return p;
}
Esempio n. 10
0
int  scan_buffer::needs_new_buffer()
{
  int buf_sz = buf_size();
  int get_sz = get_size();
  int free_sz =  buf_sz - get_sz;
  if (16 <= free_sz)
    return 0;
  else
    return (buf_sz ? 2 * buf_sz : 256);
}
Esempio n. 11
0
/**
 * Prints the host address ``ha'' followed by ``port'' to a static buffer.
 *
 * @param ha the host address.
 * @param port the port number.
 *
 * @return a pointer to a static buffer holding a NUL-terminated string
 *         representing the given host address and port.
 */
const char *
port_host_addr_to_string(uint16 port, const host_addr_t ha)
{
	buf_t *b = buf_private(G_STRFUNC, HOST_ADDR_PORT_BUFLEN);
	char *p = buf_data(b);
	size_t len, n = buf_size(b);

	len = host_port_addr_to_string_buf(port, ha, p, n);
	g_assert(len < n);
	return p;
}
Esempio n. 12
0
/**
 * Same as host_addr_to_string(), but in another static buffer.
 */
const char *
host_addr_to_string2(const host_addr_t ha)
{
	buf_t *b = buf_private(G_STRFUNC, HOST_ADDR_BUFLEN);
	char *p = buf_data(b);
	size_t len, n = buf_size(b);

	len = host_addr_to_string_buf(ha, p, n);
	g_assert(len < n);
	return p;
}
Esempio n. 13
0
/* Make more room in the buffer if needed. */
static void
buf_prewrite(struct buf *buf)
{

	if (buf_count(buf) == buf_size(buf))
		buf_grow(buf, 0);
	if (buf_count(buf) > 0 && buf_avail(buf) == 0) {
		memmove(buf->buf, buf->buf + buf->off, buf_count(buf));
		buf->off = 0;
	}
}
Esempio n. 14
0
/**
 * Pretty-print the message information.
 *
 * @param data		start of the G2 message
 * @param len		length of the message
 *
 * @return formatted static string.
 */
const char *
g2_msg_infostr(const void *data, size_t len)
{
	buf_t *b = buf_private(G_STRFUNC, 64);
	char *p = buf_data(b);
	size_t n, sz = buf_size(b);

	n = g2_msg_infostr_to_buf(data, len, p, sz);
	g_assert(n < sz);
	return p;
}
static void *
bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
{
	struct bts_buffer *buf;
	struct page *page;
	int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
	unsigned long offset;
	size_t size = nr_pages << PAGE_SHIFT;
	int pg, nbuf, pad;

	/* count all the high order buffers */
	for (pg = 0, nbuf = 0; pg < nr_pages;) {
		page = virt_to_page(pages[pg]);
		if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
			return NULL;
		pg += 1 << page_private(page);
		nbuf++;
	}

	/*
	 * to avoid interrupts in overwrite mode, only allow one physical
	 */
	if (overwrite && nbuf > 1)
		return NULL;

	buf = kzalloc_node(offsetof(struct bts_buffer, buf[nbuf]), GFP_KERNEL, node);
	if (!buf)
		return NULL;

	buf->nr_pages = nr_pages;
	buf->nr_bufs = nbuf;
	buf->snapshot = overwrite;
	buf->data_pages = pages;
	buf->real_size = size - size % BTS_RECORD_SIZE;

	for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
		unsigned int __nr_pages;

		page = virt_to_page(pages[pg]);
		__nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
		buf->buf[nbuf].page = page;
		buf->buf[nbuf].offset = offset;
		buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
		buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
		pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
		buf->buf[nbuf].size -= pad;

		pg += __nr_pages;
		offset += __nr_pages << PAGE_SHIFT;
	}

	return buf;
}
Esempio n. 16
0
static size_t jsonFetchData(void *buffer, size_t size, size_t nmemb, void *userp)
{
	buf_t *buf = (buf_t *) userp;
	size_t total = size * nmemb;

	if (buf->limit - buf->len < total) {
		buf = buf_size(buf, buf->limit + total);
	}

	buf_concat(buf, buffer, total);

	return total;
}
Esempio n. 17
0
WEAK int halide_default_device_and_host_malloc(void *user_context, struct buffer_t *buf, const halide_device_interface *device_interface) {
    size_t size = buf_size(buf);
    buf->host = (uint8_t *)halide_malloc(user_context, size);
    if (buf->host == NULL) {
        return -1;
    }
    int result = halide_device_malloc(user_context, buf, device_interface);
    if (result != 0) {
        halide_free(user_context, buf->host);
        buf->host = NULL;
    }
    return result;
}
Esempio n. 18
0
WEAK void halide_copy_to_dev(buffer_t* buf) {
    if (buf->host_dirty) {
        halide_assert(buf->host && buf->dev);
        size_t size = buf_size(buf);
        #ifdef DEBUG
        char msg[256];
        snprintf(msg, 256, "copy_to_dev (%zu bytes) %p -> %p (t=%lld)",
                 size, buf->host, (void*)buf->dev, (long long)halide_current_time_ns() );
        halide_assert(halide_validate_dev_pointer(buf));
        #endif
        TIME_CALL( cuMemcpyHtoD(buf->dev, buf->host, size), msg );
    }
    buf->host_dirty = false;
}
Esempio n. 19
0
WEAK void halide_copy_to_host(buffer_t* buf) {
    if (buf->dev_dirty) {
        halide_assert(buf->dev);
        halide_assert(buf->host);
        size_t size = buf_size(buf);
        #ifdef DEBUG
        char msg[256];
        snprintf(msg, 256, "copy_to_host (%zu bytes) %p -> %p", size, (void*)buf->dev, buf->host );
        halide_assert(halide_validate_dev_pointer(buf));
        #endif
        TIME_CALL( cuMemcpyDtoH(buf->host, buf->dev, size), msg );
    }
    buf->dev_dirty = false;
}
Esempio n. 20
0
/**
 * Convert current header to a string.
 *
 * @attention
 * NB: returns pointer to static data!
 */
const char *
header_fmt_to_string(const header_fmt_t *hf)
{
	buf_t *b = buf_private(G_STRFUNC, HEADER_FMT_MAX_SIZE + 1);
	char *p = buf_data(b);
	size_t n = buf_size(b);

	header_fmt_check(hf);

	if (str_len(hf->header) >= n) {
		g_warning("trying to format too long an HTTP line (%zu bytes)",
			str_len(hf->header));
	}
	clamp_strncpy(p, n, str_2c(hf->header), str_len(hf->header));
	return p;
}
Esempio n. 21
0
WEAK void halide_dev_malloc(buffer_t* buf) {
    if (buf->dev) {
        // This buffer already has a device allocation
        return;
    }

    #ifndef NDEBUG
    fprintf(stderr, "dev_malloc of %zdx%zdx%zdx%zd (%zd bytes per element) (buf->dev = %p) buffer\n",
            buf->extent[0], buf->extent[1], buf->extent[2], buf->extent[3], buf->elem_size, (void*)buf->dev);
    #endif    

    CUdeviceptr p;
    TIME_CALL( cuMemAlloc(&p, buf_size(buf)), "dev_malloc");
    buf->dev = (uint64_t)p;
    assert(buf->dev);

    #ifndef NDEBUG
    assert(halide_validate_dev_pointer(buf));
    #endif
}
Esempio n. 22
0
WEAK void halide_dev_malloc(buffer_t* buf) {
    if (buf->dev) {
        // This buffer already has a device allocation
        return;
    }

    size_t size = buf_size(buf);

    #ifdef DEBUG
    halide_printf("dev_malloc allocating buffer of %zd bytes, %zdx%zdx%zdx%zd (%d bytes per element)\n",
            size, buf->extent[0], buf->extent[1], buf->extent[2], buf->extent[3], buf->elem_size);
    #endif

    CUdeviceptr p;
    TIME_CALL( cuMemAlloc(&p, size), "dev_malloc");
    buf->dev = (uint64_t)p;
    halide_assert(buf->dev);

    #ifdef DEBUG
    halide_assert(halide_validate_dev_pointer(buf));
    #endif
}
Esempio n. 23
0
void RenderThread::run()
{
	logInfo("RenderThread::run : starting thread");
	while (running)
	{
		running_mutex.lock();
		RenderRequest* job;
		if (preview_request != 0)
		{
			job = preview_request;
			preview_request = 0;
		}
		else if (image_request != 0)
		{
			job = image_request;
			image_request = 0;
		}
		else
		{
			rqueue_mutex.lock();
			if (request_queue.isEmpty())
			{
				// sleep only after checking for requests
				current_request = 0;
				rqueue_mutex.unlock();
				running_mutex.unlock();
				usleep(10000);
				continue;
			}
			else
			{
				job = request_queue.dequeue();
				logFine("RenderThread::run : dequeueing request %#x", (long)job);
				rqueue_mutex.unlock();
			}
		}
		render_loop_flag = true;
		current_request = job;

		// make sure there is something to calculate
		bool no_pos_xf = true;
		for (flam3_xform* xf = job->genome()->xform ;
			 xf < job->genome()->xform + job->genome()->num_xforms ; xf++)
			if (xf->density > 0.0)
			{
				no_pos_xf = false;
				break;
			}
		if (no_pos_xf)
		{
			logWarn(QString("RenderThread::run : no xform in request 0x%1").arg((long)job,0,16));
			running_mutex.unlock();
			continue;
		}

		logFiner(QString("RenderThread::run : rendering request 0x%1").arg((long)job,0,16));
		rtype = job->name();
		flame.time = job->time();
		flame.ngenomes = job->numGenomes();
		flam3_genome* genomes = new flam3_genome[flame.ngenomes]();
		flam3_genome* job_genome = job->genome();
		for (int n = 0 ; n < flame.ngenomes ; n++)
			flam3_copy(genomes + n, job_genome + n);
		flame.genomes = genomes;
		QSize imgSize(job->size());
		if (!imgSize.isEmpty())
		{
			for (int n = 0 ; n < flame.ngenomes ; n++)
			{
				flam3_genome* genome = genomes + n;
				// scale images, previews, etc. if necessary
				int width  = genome->width;
				genome->width  = imgSize.width();
				genome->height = imgSize.height();

				// "rescale" the image scale to maintain the camera
				// for smaller/larger image size
				genome->pixels_per_unit /= ((double)width) / genome->width;
			}
		}

		// Load image quality settings for Image, Preview, and File types
		switch (job->type())
		{
			case RenderRequest::File:
				rtype = QFileInfo(job->name()).fileName();

			case RenderRequest::Image:
			case RenderRequest::Preview:
			case RenderRequest::Queued:
			{
				const flam3_genome* g = job->imagePresets();
				if (g->nbatches > 0) // valid quality settings for nbatches > 0
					for (int n = 0 ; n < flame.ngenomes ; n++)
					{
						flam3_genome* genome = genomes + n;
						genome->sample_density =            g->sample_density;
						genome->spatial_filter_radius =     g->spatial_filter_radius;
						genome->spatial_oversample =        g->spatial_oversample;
						genome->nbatches =                  g->nbatches;
						genome->ntemporal_samples =         g->ntemporal_samples;
						genome->estimator =                 g->estimator;
						genome->estimator_curve =           g->estimator_curve;
						genome->estimator_minimum =         g->estimator_minimum;
					}
			}

			default:
				;
		}

		// add symmetry xforms before rendering
		for (int n = 0 ; n < flame.ngenomes ; n++)
		{
			flam3_genome* genome = genomes + n;
			if (genome->symmetry != 1)
				flam3_add_symmetry(genome, genome->symmetry);
		}

		int msize = channels * genomes->width * genomes->height;
		unsigned char* out = new unsigned char[msize];
		unsigned char* head = out;
		logFine("RenderThread::run : allocated %d bytes, rendering...", msize);
		init_status_cb();
		rendering = true;
		ptimer.start();
		int rv = flam3_render(&flame, out, 0, channels, alpha_trans, &_stats);
		millis = ptimer.elapsed();
		rendering = false;
		render_loop_flag = false;

		if (_stop_current_job) // if stopRendering() is called
		{
			logFine(QString("RenderThread::run : %1 rendering stopped").arg(rtype));
			delete[] head;
			for (int n = 0 ; n < flame.ngenomes ; n++)
				clear_cp(genomes + n, flam3_defaults_off);
			delete[] genomes;
			if (kill_all_jobs)
			{
				preview_request = 0;
				image_request = 0;
				rqueue_mutex.lock();
				request_queue.clear();
				rqueue_mutex.unlock();
				kill_all_jobs = false;
				emit flameRenderingKilled();
			}
			else
				if (job->type() == RenderRequest::Queued)
				{
					logFine("RenderThread::run : re-adding queued request");
					rqueue_mutex.lock();
					request_queue.prepend(job);
					rqueue_mutex.unlock();
				}

			_stop_current_job = false;
			running_mutex.unlock();
			continue;
		}

		QSize buf_size(genomes->width, genomes->height);
		if (img_format == RGB32)
		{
			if (buf_size != img_buf.size())
				img_buf = QImage(buf_size, QImage::Format_RGB32);
			if (rv == 0)
			{
				for (int h = 0 ; h < genomes->height ; h++)
					for (int w = 0 ; w < genomes->width ; w++, out += channels)
						img_buf.setPixel(QPoint(w, h), qRgb(out[0], out[1], out[2]));
			}
			else
				img_buf.fill(0);
		}
		else
		{
			if (buf_size != img_buf.size())
				img_buf = QImage(buf_size, QImage::Format_ARGB32);
			if (rv == 0)
			{
				for (int h = 0 ; h < genomes->height ; h++)
					for (int w = 0 ; w < genomes->width ; w++, out += channels)
						img_buf.setPixel(QPoint(w, h), qRgba(out[0], out[1], out[2], out[3]));
			}
			else
				img_buf.fill(0);
		}
		delete[] head;
		for (int n = 0 ; n < flame.ngenomes ; n++)
			clear_cp(genomes + n, flam3_defaults_off);
		delete[] genomes;

		if (job->type() == RenderRequest::File)
			img_buf.save(job->name(), "png", 100);

		job->setImage(img_buf);
		job->setFinished(true);

		// look for a free event
		RenderEvent* event = 0;
		foreach (RenderEvent* e, event_list)
			if (e->accepted())
			{
				e->accept(false);
				event = e;
				break;
			}

		if (!event)
		{
			logFinest(QString("RenderThread::run : adding event"));
			event = new RenderEvent();
			event->accept(false);
			event_list.append(event);
		}
		logFiner(QString("RenderThread::run : event list size %1")
				.arg(event_list.size()));

		event->setRequest(job);
		emit flameRendered(event);
		logFiner(QString("RenderThread::run : finished"));
		running_mutex.unlock();
	}

	logInfo("RenderThread::run : thread exiting");
}
Esempio n. 24
0
static bool block_fits(struct k_mem_pool *p, void *block, size_t bsz)
{
	return (block + bsz - 1 - p->buf) < buf_size(p);
}
static int
bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
{
	unsigned long head, space, next_space, pad, gap, skip, wakeup;
	unsigned int next_buf;
	struct bts_phys *phys, *next_phys;
	int ret;

	if (buf->snapshot)
		return 0;

	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
	if (WARN_ON_ONCE(head != local_read(&buf->head)))
		return -EINVAL;

	phys = &buf->buf[buf->cur_buf];
	space = phys->offset + phys->displacement + phys->size - head;
	pad = space;
	if (space > handle->size) {
		space = handle->size;
		space -= space % BTS_RECORD_SIZE;
	}
	if (space <= BTS_SAFETY_MARGIN) {
		/* See if next phys buffer has more space */
		next_buf = buf->cur_buf + 1;
		if (next_buf >= buf->nr_bufs)
			next_buf = 0;
		next_phys = &buf->buf[next_buf];
		gap = buf_size(phys->page) - phys->displacement - phys->size +
		      next_phys->displacement;
		skip = pad + gap;
		if (handle->size >= skip) {
			next_space = next_phys->size;
			if (next_space + skip > handle->size) {
				next_space = handle->size - skip;
				next_space -= next_space % BTS_RECORD_SIZE;
			}
			if (next_space > space || !space) {
				if (pad)
					bts_buffer_pad_out(phys, head);
				ret = perf_aux_output_skip(handle, skip);
				if (ret)
					return ret;
				/* Advance to next phys buffer */
				phys = next_phys;
				space = next_space;
				head = phys->offset + phys->displacement;
				/*
				 * After this, cur_buf and head won't match ds
				 * anymore, so we must not be racing with
				 * bts_update().
				 */
				buf->cur_buf = next_buf;
				local_set(&buf->head, head);
			}
		}
	}

	/* Don't go far beyond wakeup watermark */
	wakeup = BTS_SAFETY_MARGIN + BTS_RECORD_SIZE + handle->wakeup -
		 handle->head;
	if (space > wakeup) {
		space = wakeup;
		space -= space % BTS_RECORD_SIZE;
	}

	buf->end = head + space;

	/*
	 * If we have no space, the lost notification would have been sent when
	 * we hit absolute_maximum - see bts_update()
	 */
	if (!space)
		return -ENOSPC;

	return 0;
}
int wmain( int argc, wchar_t **argv, wchar_t **envp )
{
    std::wcout << "named pipe server" << std::endl;

    HANDLE h_wait_stop = CreateEvent( nullptr, 0, 0, nullptr );

    // We need to use overlapped IO for this, so we dont block when
    // waiting for a client to connect.  This is the only effective way
    // to handle either a client connection, or a service stop request.
    OVERLAPPED overlapped;
    overlapped.Internal = 0;
    overlapped.InternalHigh = 0;
    overlapped.Pointer = 0;

    std::wcout << "sizeof( overlapperd ) " << sizeof( overlapped ) << std::endl;
    std::wcout << "sizeof( overlapperd.Internal ) " << sizeof( overlapped.Internal ) << std::endl;
    std::wcout << "sizeof( overlapperd.InternalHigh ) " << sizeof( overlapped.InternalHigh ) << std::endl;
    std::wcout << "sizeof( overlapperd.Pointer ) " << sizeof( overlapped.Pointer ) << std::endl;
    std::wcout << "sizeof( overlapperd.hEvent ) " << sizeof( overlapped.hEvent ) << std::endl;

    // And create an event to be used in the OVERLAPPED object.
    overlapped.hEvent = CreateEventW( nullptr, 0, 0, nullptr );

    // We create our named pipe.
    char *pipe_name = "\\\\.\\pipe\\Barry's Emacs 8.2";

    HANDLE h_pipe = CreateNamedPipeA(
                    pipe_name,                      //  __in      LPCTSTR lpName,
                    PIPE_ACCESS_DUPLEX
                    | FILE_FLAG_OVERLAPPED,         //  __in      DWORD dwOpenMode,
                    PIPE_TYPE_MESSAGE
                    | PIPE_READMODE_MESSAGE
                    | PIPE_REJECT_REMOTE_CLIENTS,   //  __in      DWORD dwPipeMode,
                    PIPE_UNLIMITED_INSTANCES,       //  __in      DWORD nMaxInstances,
                    0,                              //  __in      DWORD nOutBufferSize,
                    0,                              //  __in      DWORD nInBufferSize,
                    100,                            //  __in      DWORD nDefaultTimeOut, (100ms)
                    nullptr                            //  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes
                    );
    if( h_pipe == 0 )
    {
        std::wcerr << "Failed to CreateNamedPipeA: " << __getLastErrorMessage().c_str() << std::endl;
        return 1;
    }

    // Loop accepting and processing connections
    for(;;)
    {
        std::wcout << "__windowsCommandLineHandler loop top" << std::endl;

        DWORD hr = ConnectNamedPipe( h_pipe, &overlapped );
        if( hr == ERROR_PIPE_CONNECTED )
        {
            // Client is fast, and already connected - signal event
            SetEvent( overlapped.hEvent );
        }

        std::wcout << "__windowsCommandLineHandler connected to named pipe" << std::endl;

        // Wait for either a connection, or a service stop request.
        HANDLE wait_handles[2];
        wait_handles[0] = h_wait_stop;
        wait_handles[1] = overlapped.hEvent;

        std::wcout << "__windowsCommandLineHandler WaitForMultipleObjects..." << std::endl;
        DWORD rc = WaitForMultipleObjects( 2, wait_handles, 0, INFINITE );

        if( rc == WAIT_OBJECT_0 )
        {
            std::wcout << "__windowsCommandLineHandler Stop event" << std::endl;
            // Stop event
            break;
        }
        else
        {
            std::wcout << "__windowsCommandLineHandler data ready for read" << std::endl;

            // Pipe event - read the data, and write it back.
            char buf_client[32768];
            DWORD buf_size( sizeof( buf_client )-1 );
            hr = ReadFile( h_pipe, buf_client, buf_size, &buf_size, nullptr );
            if( !hr )
            {
                std::wcout << "ReadFile failed: " << __getLastErrorMessage().c_str() << std::endl;
            }
            else
            {
                buf_client[ buf_size ] = 0;
                std::wcout << "__windowsCommandLineHandler read command size " << buf_size << " \"" << buf_client << "\"" << std::endl;

                if( buf_size > 0 )
                {
                    char *reply = "Reply";
                    DWORD reply_size = strlen( reply );

                    hr = WriteFile( h_pipe, reply, reply_size, &reply_size, nullptr );
                    if( !hr )
                    {
                        std::wcout << "WriteFile failed: " << __getLastErrorMessage().c_str() << std::endl;
                    }
                }
            }
            // And disconnect from the client.
            DisconnectNamedPipe( h_pipe );
            std::wcout << "__windowsCommandLineHandler Disconnected named pipe" << std::endl;
        }
    }
    return 0;
}