static void
check_value (void *cls, const GNUNET_HashCode * key, size_t size,
             const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
             uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
             uint64_t uid)
{
  struct CpsRunContext *crc = cls;
  int i;

  if (NULL == key)
  {
    crc->phase = RP_GET_FAIL;
    GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    return;
  }
  i = crc->i;
  GNUNET_assert (size == get_size (i));
  GNUNET_assert (0 == memcmp (data, get_data (i), size));
  GNUNET_assert (type == get_type (i));
  GNUNET_assert (priority == get_priority (i));
  GNUNET_assert (anonymity == get_anonymity (i));
  GNUNET_assert (expiration.abs_value == get_expiration (i).abs_value);
  crc->offset++;
  crc->i--;
  if (crc->i == 0)
    crc->phase = RP_DONE;
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
static void
run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct CpsRunContext *crc = cls;

  ok = (int) crc->phase;
  switch (crc->phase)
  {
  case RP_PUT:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "PUT",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i),
                          get_data (crc->i), get_type (crc->i),
                          get_priority (crc->i), get_anonymity (crc->i), 0,
                          get_expiration (crc->i), 1, 1, TIMEOUT,
                          &check_success, crc);
    crc->i++;
    if (crc->i == ITERATIONS)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Sleeping to give datastore time to clean up\n");
      sleep (1);
      crc->phase = RP_GET;
      crc->i--;
    }
    break;
  case RP_GET:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key,
                              get_type (crc->i), 1, 1, TIMEOUT, &check_value,
                              crc);
    break;
  case RP_GET_FAIL:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key,
                              get_type (crc->i), 1, 1, TIMEOUT, &check_nothing,
                              crc);
    break;
  case RP_DONE:
    GNUNET_assert (0 == crc->i);
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished, disconnecting\n");
#endif
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    ok = 0;
  }
}
static ssize_t
_mongoc_stream_socket_writev (mongoc_stream_t *stream,
                              mongoc_iovec_t *iov,
                              size_t iovcnt,
                              int32_t timeout_msec)
{
   mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream;
   int64_t expire_at;
   ssize_t ret;

   ENTRY;

   if (ss->sock) {
      expire_at = get_expiration (timeout_msec);
      ret = mongoc_socket_sendv (ss->sock, iov, iovcnt, expire_at);
      errno = mongoc_socket_errno (ss->sock);
      RETURN (ret);
   }

   RETURN (-1);
}
static ssize_t
_mongoc_stream_socket_readv (mongoc_stream_t *stream,
                             mongoc_iovec_t *iov,
                             size_t iovcnt,
                             size_t min_bytes,
                             int32_t timeout_msec)
{
   mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream;
   int64_t expire_at;
   ssize_t ret = 0;
   ssize_t nread;
   size_t cur = 0;

   ENTRY;

   BSON_ASSERT (ss);
   BSON_ASSERT (ss->sock);

   expire_at = get_expiration (timeout_msec);

   /*
    * This isn't ideal, we should plumb through to recvmsg(), but we
    * don't actually use this in any way but to a single buffer
    * currently anyway, so should be just fine.
    */

   for (;;) {
      nread = mongoc_socket_recv (
         ss->sock, iov[cur].iov_base, iov[cur].iov_len, 0, expire_at);

      if (nread <= 0) {
         if (ret >= (ssize_t) min_bytes) {
            RETURN (ret);
         }
         errno = mongoc_socket_errno (ss->sock);
         RETURN (-1);
      }

      ret += nread;

      while ((cur < iovcnt) && (nread >= (ssize_t) iov[cur].iov_len)) {
         nread -= iov[cur++].iov_len;
      }

      if (cur == iovcnt) {
         break;
      }

      if (ret >= (ssize_t) min_bytes) {
         RETURN (ret);
      }

      iov[cur].iov_base = ((char *) iov[cur].iov_base) + nread;
      iov[cur].iov_len -= nread;

      BSON_ASSERT (iovcnt - cur);
      BSON_ASSERT (iov[cur].iov_len);
   }

   RETURN (ret);
}