Beispiel #1
0
gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, unsigned n) {
  gpr_slice *back;
  gpr_uint8 *out;

  sb->length += n;

  if (sb->count == 0) goto add_new;
  back = &sb->slices[sb->count - 1];
  if (back->refcount) goto add_new;
  if ((back->data.inlined.length + n) > sizeof(back->data.inlined.bytes))
    goto add_new;
  out = back->data.inlined.bytes + back->data.inlined.length;
  back->data.inlined.length += n;
  return out;

add_new:
  if (sb->count == sb->capacity) {
    sb->capacity = GROW(sb->capacity);
    GPR_ASSERT(sb->capacity > sb->count);
    sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
  }
  back = &sb->slices[sb->count];
  sb->count++;
  back->refcount = NULL;
  back->data.inlined.length = n;
  return back->data.inlined.bytes;
}
Beispiel #2
0
static grpc_stream_op *add(grpc_stream_op_buffer *sopb) {
  grpc_stream_op *out;

  if (sopb->nops == sopb->capacity) {
    expandto(sopb, GROW(sopb->capacity));
  }
  out = sopb->ops + sopb->nops;
  sopb->nops++;
  return out;
}
Beispiel #3
0
size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice s) {
  size_t out = sb->count;
  if (out == sb->capacity) {
    sb->capacity = GROW(sb->capacity);
    GPR_ASSERT(sb->capacity > sb->count);
    sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
  }
  sb->slices[out] = s;
  sb->length += GPR_SLICE_LENGTH(s);
  sb->count = out + 1;
  return out;
}
Beispiel #4
0
static void maybe_embiggen(gpr_slice_buffer *sb) {
  if (sb->count == sb->capacity) {
    sb->capacity = GROW(sb->capacity);
    GPR_ASSERT(sb->capacity > sb->count);
    if (sb->slices == sb->inlined) {
      sb->slices = gpr_malloc(sb->capacity * sizeof(gpr_slice));
      memcpy(sb->slices, sb->inlined, sb->count * sizeof(gpr_slice));
    } else {
      sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
    }
  }
}
Beispiel #5
0
void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
                      size_t nops) {
  size_t orig_nops = sopb->nops;
  size_t new_nops = orig_nops + nops;

  if (new_nops > sopb->capacity) {
    expandto(sopb, GPR_MAX(GROW(sopb->capacity), new_nops));
  }

  memcpy(sopb->ops + orig_nops, ops, sizeof(grpc_stream_op) * nops);
  sopb->nops = new_nops;
}
Beispiel #6
0
void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice s) {
  size_t n = sb->count;
  /* if both the last slice in the slice buffer and the slice being added
     are inlined (that is, that they carry their data inside the slice data
     structure), and the back slice is not full, then concatenate directly
     into the back slice, preventing many small slices being passed into
     writes */
  if (!s.refcount && n) {
    gpr_slice *back = &sb->slices[n - 1];
    if (!back->refcount && back->data.inlined.length < GPR_SLICE_INLINED_SIZE) {
      if (s.data.inlined.length + back->data.inlined.length <=
          GPR_SLICE_INLINED_SIZE) {
        memcpy(back->data.inlined.bytes + back->data.inlined.length,
               s.data.inlined.bytes, s.data.inlined.length);
        back->data.inlined.length += s.data.inlined.length;
      } else {
        size_t cp1 = GPR_SLICE_INLINED_SIZE - back->data.inlined.length;
        memcpy(back->data.inlined.bytes + back->data.inlined.length,
               s.data.inlined.bytes, cp1);
        back->data.inlined.length = GPR_SLICE_INLINED_SIZE;
        if (n == sb->capacity) {
          sb->capacity = GROW(sb->capacity);
          GPR_ASSERT(sb->capacity > sb->count);
          sb->slices =
              gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
        }
        back = &sb->slices[n];
        sb->count = n + 1;
        back->refcount = NULL;
        back->data.inlined.length = s.data.inlined.length - cp1;
        memcpy(back->data.inlined.bytes, s.data.inlined.bytes + cp1,
               s.data.inlined.length - cp1);
      }
      sb->length += s.data.inlined.length;
      return; /* early out */
    }
  }
  gpr_slice_buffer_add_indexed(sb, s);
}
Beispiel #7
0
int integer_square(integer_t target, integer_t source) {
  bool aliased;
  integer_t result;
  
  if(integer_is_zero(source)) { return integer_set_unsigned_value(target, 0); }
  
  aliased = (result == source);
  result = aliased ? integer_create(0) : target;

  VERIFY(GROW(result, 2 * LENGTH(source)));
  SET_SIGNED_LENGTH(result, 2 * LENGTH(source));

  VERIFY(digits_square(DIGITS(result), DIGITS(source), LENGTH(source)));
  NORMALIZE(result);

  // TODO: call a karatsuba routine here...

  if(aliased) {
    EXCHANGE(target, result);
    integer_destroy(result);
  }

  return 0;  
}
Beispiel #8
0
static void ringhelper_update (ringhelper *self, int nph, int mmax, double phi0)
  {
  int m;
  self->norot = (fabs(phi0)<1e-14);
  if (!(self->norot))
    if ((mmax!=self->s_shift-1) || (!FAPPROX(phi0,self->phi0_,1e-12)))
      {
      RESIZE (self->shiftarr,pshtd_cmplx,mmax+1);
      self->s_shift = mmax+1;
      self->phi0_ = phi0;
      for (m=0; m<=mmax; ++m)
        {
        self->shiftarr[m].re = cos(m*phi0);
        self->shiftarr[m].im = sin(m*phi0);
        }
      }
  if (!self->plan) self->plan=make_real_plan(nph);
  if (nph!=(int)self->plan->length)
    {
    kill_real_plan(self->plan);
    self->plan=make_real_plan(nph);
    }
  GROW(self->work,pshtd_cmplx,self->s_work,nph);
  }
Beispiel #9
0
/**
 * Make sure the DB is current and then go into FAM-monitored mode
 * updating the DB all the time in the background.  Exits after a
 * signal (i.e.  SIGHUP/SIGINT) is received.
 */
static int build(const char * libraries,
		 const char * dbName,
		 size_t mem_limit,
		 const char * log,
		 int argc,		
		 char * argv[]) {
  int i;
  unsigned int ret;
  DIC cls;
  char * ename;
  FILE * logfile;
  PTHREAD_T workerThread;
  void * unused;

  cls.argc = argc;
  cls.argv = argv;
  cls.deferredCount = 0;
  cls.deferredTruncations = NULL;
  logfile = NULL;
  if (log != NULL) {
    logfile = fopen(log, "w+");
    if (logfile == NULL)
      my_log(stderr,
	     DOODLE_LOG_CRITICAL,
	     _("Could not open '%s' for logging: %s.\n"),
	     log,
	     strerror(errno));
  }
  cls.logContext = logfile;
  cls.log = &my_log;


  if (dbName == NULL) {
    my_log(logfile,
	   DOODLE_LOG_CRITICAL,
	   _("No database specified.  Aborting.\n"));
    return -1;
  }
  for (i=strlen(dbName);i>=0;i--) {
    if (dbName[i] == ':') {
      my_log(logfile,
	     DOODLE_LOG_CRITICAL,
	     _("'%s' is an invalid database filename (has a colon) for building database (option '%s').\n"),
	     dbName,
	     "-b");
      return -1;
    }
  }
  ename = expandFileName(dbName);
  if (ename == NULL)
    return -1;
  cls.ename = ename;
  cls.tree = DOODLE_tree_create(&my_log,
				logfile,
				ename);
  cls.treePresent = 1;
  if (cls.tree == NULL)
    return -1;
  if (mem_limit != 0)
    DOODLE_tree_set_memory_limit(cls.tree,
				 mem_limit);
  cls.elist = forkExtractor(do_default,
			    libraries,
			    &my_log,
			    logfile);
  if (cls.elist == NULL) {
    DOODLE_tree_destroy(cls.tree);
    return -1;
  }
  if (0 != FAMOpen2(&cls.fc, "doodled")) {
    my_log(logfile,
	   DOODLE_LOG_CRITICAL,
	   _("Failed to connect to fam.  Aborting.\n"));
    DOODLE_tree_destroy(cls.tree);
    return -1;
  }
  cls.fr = NULL;
  cls.frPos = 0;
  cls.frSize = 0;
  GROW(cls.fr,
       cls.frSize,
       128);
  cls.frNames = NULL;
  ret = 0;
  GROW(cls.frNames,
       ret,
       128);
  ret = 0;


  MUTEX_CREATE(&cls.lock);
  if (0 != PTHREAD_CREATE(&workerThread,
			  &worker,
			  &cls,
			  64 * 1024)) {
    my_log(logfile,
	   DOODLE_LOG_CRITICAL,
	   _("Failed to create worker thread: %s"),
	   strerror(errno));
    ret = -1;
  } else {
    wait_for_shutdown();
    cls.continueRunning = 0;
    SEMAPHORE_UP(cls.signal);
    PTHREAD_JOIN(&workerThread, &unused);
  }
  MUTEX_DESTROY(&cls.lock);

  my_log(logfile,
	 DOODLE_LOG_VERBOSE,
	 _("doodled is shutting down.\n"));
  if (cls.frPos == 0) {
    my_log(logfile,
	   DOODLE_LOG_CRITICAL,
	   _("No files exist that doodled would monitor for changes.  Exiting.\n"));
  }


  for (i=0;i<cls.frSize;i++) {
    if (cls.frNames[i] != NULL) {
      my_log(logfile,
	     DOODLE_LOG_VERBOSE,
	     _("Cancelling fam monitor '%s'.\n"),
	     cls.frNames[i]);
      free(cls.frNames[i]);
    }
  }

  for (i=cls.deferredCount-1;i>=0;i--)
    free(cls.deferredTruncations[i]);
  GROW(cls.deferredTruncations,
       cls.deferredCount,
       0);
  i = cls.frSize;
  GROW(cls.fr,
       cls.frSize,
       0);
  cls.frSize = i;
  GROW(cls.frNames,
       cls.frSize,
       0);
  my_log(logfile,
	 DOODLE_LOG_VERBOSE,
	 _("Unloading libextractor plugins.\n"));
  joinExtractor(cls.elist);
  free(ename);
  if (logfile != NULL)
    fclose(logfile);
  return ret;
}
Beispiel #10
0
/**
 * Main worker thread.  Register FAM events and process.
 */
static void * worker(void * arg) {
  DIC * cls = arg;
  int i;
  int more;
  int wasMore;
  int ret;
  void * unused;
  char * fn;
  PTHREAD_T helperThread;

  cls->log(cls->logContext,
	   DOODLE_LOG_VERY_VERBOSE,
	   _("Main worker thread created.\n"));
  cls->eventCount = 0;
  cls->continueRunning = 1;
  cls->events = NULL;
  cls->signal = SEMAPHORE_NEW(0);
  if (0 != PTHREAD_CREATE(&helperThread,
			  &processEvents,
			  cls,
			  64 * 1024)) {
    cls->log(cls->logContext,
	     DOODLE_LOG_CRITICAL,
	     _("Failed to spawn event processing thread.\n"));
    run_shutdown(0);
    return NULL;
  }

  cls->log(cls->logContext,
	   DOODLE_LOG_VERBOSE,
	   _("Registering with FAM for file system events.\n"));
  for (i=0;i<cls->argc;i++) {
    char * exp;

    cls->log(cls->logContext,
	     DOODLE_LOG_VERY_VERBOSE,
	     _("Indexing '%s'\n"),
	     cls->argv[i]);
    exp = expandFileName(cls->argv[i]);
    if (-1 == do_index(exp,
		       cls)) {
      ret = -1;
      free(exp);
      break;
    }
    free(exp);
  }
  DOODLE_tree_destroy(cls->tree);
  cls->treePresent = 0;
  cls->tree = NULL;

  cls->log(cls->logContext,
	   DOODLE_LOG_VERBOSE,
	   _("doodled startup complete.  Now waiting for FAM events.\n"));

  wasMore = 0;
  while ( (cls->continueRunning) &&
	  (0 == testShutdown()) ) {
    SEMAPHORE_DOWN(cls->signal);
    cls->log(cls->logContext,
	     DOODLE_LOG_INSANELY_VERBOSE,
	     "Received signal to process fam event.\n");
    MUTEX_LOCK(&cls->lock);
    if (cls->eventCount > 0) {
      fn = cls->events[cls->eventCount-1];
      GROW(cls->events,
	   cls->eventCount,
	   cls->eventCount-1);
      more = cls->eventCount > 0;
      cls->log(cls->logContext,
	       DOODLE_LOG_INSANELY_VERBOSE,
	       "Processing fam event '%s'.\n",
	       fn);
    } else {
      fn = NULL;
      more = 0;
    }
    if (! wasMore) {
      cls->treePresent++;
      if (cls->treePresent == 1)
	cls->tree = DOODLE_tree_create((DOODLE_Logger) cls->log,
				       cls->logContext,
				       cls->ename);
    }
    MUTEX_UNLOCK(&cls->lock);
    if (fn != NULL) {
      do_index(fn, cls);
      free(fn);
    }
    MUTEX_LOCK(&cls->lock);
    if (! more) {
      cls->treePresent--;
      if (cls->treePresent == 0)
	DOODLE_tree_destroy(cls->tree);
    }
    MUTEX_UNLOCK(&cls->lock);
    wasMore = more;
  } /* forever (until signal) */

  cls->continueRunning = 0;
  if (0 != FAMClose(&cls->fc)) {
    cls->log(cls->logContext,
	   DOODLE_LOG_CRITICAL,
	   _("Error disconnecting from fam.\n"));
  }
  PTHREAD_KILL(&helperThread, SIGTERM);
  PTHREAD_JOIN(&helperThread, &unused);
  SEMAPHORE_FREE(cls->signal);

  if (cls->treePresent > 0)
    DOODLE_tree_destroy(cls->tree);
  return NULL;
}
Beispiel #11
0
static int do_index(const char * filename,
		    DIC * dic) {
  int i;
  int j;
  int k;
  struct stat sbuf;

  if (0 == strncmp(filename,
		   dic->ename,
		   strlen(dic->ename)))
    return 0; /* database (and database-temp file) is always pruned! */

  if (isPruned(filename))
    return 0;
  for (i=dic->deferredCount-1;i>=0;i--) {
    if (0 == strcmp(filename,
		    dic->deferredTruncations[i])) {
      free(dic->deferredTruncations[i]);
      dic->deferredTruncations[i]
	= dic->deferredTruncations[dic->deferredCount-1];
      GROW(dic->deferredTruncations,
	   dic->deferredCount,
	   dic->deferredCount-1);
    }
  }

  j = -1;
  for (i=DOODLE_getFileCount(dic->tree)-1;i>=0;i--) {
    if (0 == strcmp(filename,
		    DOODLE_getFileAt(dic->tree,i)->filename)) {
      j = i;
      break;
    }
  }

  k = -1;
  for (i=0;i<dic->frPos;i++) {
    if (0 == strcmp(filename,
		    dic->frNames[i])) {
      k=i;
      break;
    }
  }

  if (0 != lstat(filename,
		 &sbuf)) {
    dic->log(dic->logContext,
	     DOODLE_LOG_VERY_VERBOSE,
	     _("Call to '%s' for file '%s' failed: %s\n"),
	     "stat",
	     filename,
	     strerror(errno));
    if (j != -1) {
      /* remove old keywords, file no longer there? */
      GROW(dic->deferredTruncations,
	   dic->deferredCount,
	   dic->deferredCount + 1);
      dic->deferredTruncations[dic->deferredCount-1]
	= strdup(filename);
    }
    if (k != -1) {
      if (-1 == FAMCancelMonitor(&dic->fc,
				 &dic->fr[k])) {
	dic->log(dic->logContext,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' for file '%s' failed: %s\n"),
		 "FAMCancelMonitor",
		 filename,
		 FamErrlist[FAMErrno]);
      }
      free(dic->frNames[k]);
      dic->fr[k] = dic->fr[dic->frPos-1];
      dic->frNames[k] = dic->frNames[dic->frPos-1];
      dic->frNames[dic->frPos-1] = NULL;
      dic->frPos--;
    }
    return 0;
  }

  if ( (S_ISDIR(sbuf.st_mode)) &&
#ifdef S_ISLNK
       (! S_ISLNK(sbuf.st_mode)) &&
#endif
#ifdef S_ISSOCK
       (! S_ISSOCK(sbuf.st_mode)) &&
#endif
       (k == -1) ) {
    char * fn;
    if (dic->frPos == dic->frSize) {
      unsigned int s = dic->frSize;
      GROW(dic->fr,
	   dic->frSize,
	   dic->frSize * 2);
      GROW(dic->frNames,
	   s,
	   s * 2);
    }
    dic->log(dic->logContext,
	     DOODLE_LOG_VERY_VERBOSE,
	     _("Will monitor directory '%s' for changes.\n"),
	     filename);
    fn = STRDUP(filename);
    if (0 == FAMMonitorDirectory(&dic->fc,
				 filename,
				 &dic->fr[dic->frPos],
				 fn)) {
      dic->frNames[dic->frPos] = fn;
      dic->frPos++;
    } else {
      dic->log(dic->logContext,
	       DOODLE_LOG_CRITICAL,
	       _("Call to '%s' for file '%s' failed: %s\n"),
	       "FAMMonitorDirectory",
	       filename,
	       FamErrlist[FAMErrno]);
      free(fn);
    }
  }

  if (j != -1) {
    if (DOODLE_getFileAt(dic->tree,j)->mod_time == (unsigned int) sbuf.st_mtime) {
      return 0; /* already processed! */
    } else {
      /* remove old keywords, file changed! */
      /* we must do the new truncation now, so
	 we also do all of those that were
	 deferred */
      GROW(dic->deferredTruncations,
	   dic->deferredCount,
	   dic->deferredCount + 2);
      dic->deferredTruncations[dic->deferredCount-2]
	= strdup(filename);

      DOODLE_tree_truncate_multiple(dic->tree,
				    (const char**)dic->deferredTruncations);
      for (i=dic->deferredCount-2;i>=0;i--)
	free(dic->deferredTruncations[i]);
      GROW(dic->deferredTruncations,
	   dic->deferredCount,
	   0);
    }
  }

  if (S_ISREG(sbuf.st_mode)) {
    dic->log(dic->logContext,
	     DOODLE_LOG_VERY_VERBOSE,
	     _("Processing file '%s'.\n"),
	     filename);
    return buildIndex(dic->elist,
		      NULL, 
		      filename,
		      dic->tree,
		      do_filenames);
  }

  return 0;
}
Beispiel #12
0
/**
 * Process all pending events.
 * Helper thread for the worker thread.  Just there
 * to process FAM events.  Puts all events into the
 * queue for the main worker.
 */
static void * processEvents(void * arg) {
  DIC * cls = arg;
  FAMEvent fe;
  fd_set r;
  fd_set w;
  fd_set e;
  int fd = cls->fc.fd;
  int i;

  cls->log(cls->logContext,
	   DOODLE_LOG_VERY_VERBOSE,
	   _("Event processing thread created.\n"));
  while ( (0 == testShutdown()) &&
	  (cls->continueRunning) ) {
    char * name;

    FD_ZERO(&r);
    FD_ZERO(&w);
    FD_ZERO(&e);
    FD_SET(fd, &r);
    i = select(fd+1, &r, &w, &e, NULL);
    if (i == -1) {
      if (errno == EINTR)
	continue;
      cls->log(cls->logContext,
	       DOODLE_LOG_CRITICAL,
	       _("Call to '%s' failed: %s\n"),
	       "select",
	       strerror(errno));
    }
    if (!FD_ISSET(fd, &r))
      continue;

    if (! FAMPending(&cls->fc)) {
      /* this should only happen if there was a problem with
	 select, and in this case we better add some artificial
	 delay (busy waiting) */
      sleep(1);
      continue;
    }

    MUTEX_LOCK(&cls->lock);
    if (-1 == FAMNextEvent(&cls->fc, &fe)) {
      cls->log(cls->logContext,
	       DOODLE_LOG_CRITICAL,
	       _("Call to '%s' failed: %s\n"),
	       "FAMNextEvent",
	       FamErrlist[FAMErrno]);
      /* avoid fast, persistent errors */
      sleep(1);
      continue;
    }
    name = malloc(strlen(fe.filename) + strlen((char*) fe.userdata) + 2);
    if (fe.filename[0] == '/') {
      strcpy(name, fe.filename);
    } else {
      strcpy(name, (char*) fe.userdata);
      if ( (strlen((char*)fe.userdata) > 0) &&
	   (((char*)fe.userdata)[strlen(fe.userdata)-1] != DIR_SEPARATOR) )
	strcat(name, DIR_SEPARATOR_STR);
      strcat(name, fe.filename);
    }
    /* never process the doodle database itself... */
    if (0 == strncmp(name,
		     cls->ename,
		     strlen(cls->ename))) {
      free(name);
      MUTEX_UNLOCK(&cls->lock);
      continue;
    }


    cls->log(cls->logContext,
	     DOODLE_LOG_INSANELY_VERBOSE,
	     "FAM EVENT (%d,%s,%s) on file '%s'.\n",
	     fe.code,
	     fe.userdata,
	     fe.filename,
	     name);
    switch (fe.code) {
    case FAMCreated:
    case FAMChanged:	
    case FAMDeleted:
    case FAMMoved:
    case FAMAcknowledge:
    case FAMExists:
    case FAMEndExist:
      GROW(cls->events,
	   cls->eventCount,
	   cls->eventCount+1);
      cls->events[cls->eventCount-1] = strdup(name);
      SEMAPHORE_UP(cls->signal);
      break;	
    default:
      break;
    } /* end switch */
    free(name);
    MUTEX_UNLOCK(&cls->lock);
  } /* if event */
  cls->continueRunning = 0;
  SEMAPHORE_UP(cls->signal);

  return NULL;
}