Пример #1
0
int main(int argc, char *argv[])
{
	int error __unused, i, r, s;
	FILE *pidf;
	int ch = 0;

	while ((ch = getopt(argc, argv, "d")) != -1) {
		switch(ch) {
		case 'd':
			debugopt = 1;
			break;
		default:
			usage();
			/* NOT REACHED */
		}
	}
	argc -= optind;
	argv += optind;

	TAILQ_INIT(&pdev_array_list);
	TAILQ_INIT(&udev_monitor_list);

	r = ignore_signal(SIGPIPE);
	if (r != 0)
		err(1, "could not ignore_signal SIGPIPE");

	r = pthread_mutex_init(&(monitor_lock), NULL);
	if (r != 0)
		err(1, "could not allocate a pthread_mutex");

	if ((udevfd = open(UDEV_DEVICE_PATH, O_RDWR | O_NONBLOCK)) == -1)
		err(1, "%s", UDEV_DEVICE_PATH);
	unblock_descriptor(udevfd);

	s = init_local_server(LISTEN_SOCKET_FILE, SOCK_STREAM, 0);
	if (s < 0)
		err(1, "init_local_server");

	pidf = fopen("/var/run/udevd.pid", "w");
#if 0
	if (pidf == NULL)
		err(1, "pidfile");
#endif

	set_signal(SIGTERM, killed);
	set_signal(SIGHUP, hangup);

	if (debugopt == 0)
		if (daemon(0, 0) == -1)
			err(1, "daemon");

	if (pidf != NULL) {
		fprintf(pidf, "%ld\n", (long)getpid());
		fclose(pidf);
	}

	syslog(LOG_ERR, "udevd started");

	pdev_array_entry_insert(udev_getdevs(udevfd));

	memset(fds, 0 , sizeof(fds));
	fds[UDEV_DEVICE_FD_IDX].fd = udevfd;
	fds[UDEV_DEVICE_FD_IDX].events = POLLIN;
	fds[UDEV_SOCKET_FD_IDX].fd = s;
	fds[UDEV_SOCKET_FD_IDX].events = POLLIN | POLLPRI;

	for (;;) {
		r = poll(fds, NFDS, -1);
		if (r < 0) {
			if (hangup_ongoing == 0) {
				if (errno == EINTR) {
					usleep(5000);
					continue;
				} else {
					err(1, "polling...");
				}
			} else {
				usleep(20000); /* 20 ms */
				continue;
			}
		}

		for (i = 0; (i < NFDS) && (r > 0); i++) {
			if (fds[i].revents == 0)
				continue;

			--r;
			switch (i) {
			case UDEV_DEVICE_FD_IDX:
				udev_read_event(udevfd);
				break;
			case UDEV_SOCKET_FD_IDX:
				handle_new_connection(s);
				break;
			default:
				break;
			}
		}
	}

	syslog(LOG_ERR, "udevd is exiting normally");
	return 0;
}
Пример #2
0
/* See Porting Layer Definition - p. 20 */
Bool
winFinishScreenInitFB (int index,
		       ScreenPtr pScreen,
		       int argc, char **argv)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  VisualPtr		pVisual = NULL;
  char			*pbits = NULL;
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
  int			iReturn;
#endif

  /* Create framebuffer */
  if (!(*pScreenPriv->pwinAllocateFB) (pScreen))
    {
      ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
      return FALSE;
    }

  /*
   * Grab the number of bits that are used to represent color in each pixel.
   */
  if (pScreenInfo->dwBPP == 8)
    pScreenInfo->dwDepth = 8;
  else
    pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
      + winCountBits (pScreenPriv->dwGreenMask)
      + winCountBits (pScreenPriv->dwBlueMask);
  
  winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n",
	  (unsigned int) pScreenPriv->dwRedMask,
	  (unsigned int) pScreenPriv->dwGreenMask,
	  (unsigned int) pScreenPriv->dwBlueMask);

  /* Init visuals */
  if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
    {
      ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n");
      return FALSE;
    }

  /* Setup a local variable to point to the framebuffer */
  pbits = pScreenInfo->pfb;
  
  /* Apparently we need this for the render extension */
  miSetPixmapDepths ();

  /* Start fb initialization */
  if (!fbSetupScreen (pScreen,
		      pScreenInfo->pfb,
		      pScreenInfo->dwWidth, pScreenInfo->dwHeight,
		      monitorResolution, monitorResolution,
		      pScreenInfo->dwStride,
		      pScreenInfo->dwBPP))
    {
      ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n");
      return FALSE;
    }

  /* Override default colormap routines if visual class is dynamic */
  if (pScreenInfo->dwDepth == 8
      && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
	  || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
	      && pScreenInfo->fFullScreen)
	  || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
	      && pScreenInfo->fFullScreen)))
    {
      winSetColormapFunctions (pScreen);

      /*
       * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its
       * own colormap, as it cannot allocate 7 planes in the default
       * colormap.  Setting whitePixel to 1 allows Magic to get 7
       * planes in the default colormap, so it doesn't create its
       * own colormap.  This latter situation is highly desireable,
       * as it keeps the Magic window viewable when switching to
       * other X clients that use the default colormap.
       */
      pScreen->blackPixel = 0;
      pScreen->whitePixel = 1;
    }

  /* Place our save screen function */
  pScreen->SaveScreen = winSaveScreen;

  /* Finish fb initialization */
  if (!fbFinishScreenInit (pScreen,
			   pScreenInfo->pfb,
			   pScreenInfo->dwWidth, pScreenInfo->dwHeight,
			   monitorResolution, monitorResolution,
			   pScreenInfo->dwStride,
			   pScreenInfo->dwBPP))
    {
      ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n");
      return FALSE;
    }

  /* Save a pointer to the root visual */
  for (pVisual = pScreen->visuals;
       pVisual->vid != pScreen->rootVisual;
       pVisual++);
  pScreenPriv->pRootVisual = pVisual;

  /* 
   * Setup points to the block and wakeup handlers.  Pass a pointer
   * to the current screen as pWakeupdata.
   */
  pScreen->BlockHandler = winBlockHandler;
  pScreen->WakeupHandler = winWakeupHandler;
  pScreen->blockData = pScreen;
  pScreen->wakeupData = pScreen;

#ifdef XWIN_MULTIWINDOWEXTWM
  /*
   * Setup acceleration for multi-window external window manager mode.
   * To be compatible with the Damage extension, this must be done
   * before calling miDCInitialize, which calls DamageSetup.
   */
  if (pScreenInfo->fMWExtWM)
    {
      if (!RootlessAccelInit (pScreen))
        {
          ErrorF ("winFinishScreenInitFB - RootlessAccelInit () failed\n");
          return FALSE;
        }
    }
#endif

#ifdef RENDER
  /* Render extension initialization, calls miPictureInit */
  if (!fbPictureInit (pScreen, NULL, 0))
    {
      ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n");
      return FALSE;
    }
#endif

#ifdef RANDR
  /* Initialize resize and rotate support */
  if (!winRandRInit (pScreen))
    {
      ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n");
      return FALSE;
    }
#endif

  /*
   * Backing store support should reduce network traffic and increase
   * performance.
   */
  miInitializeBackingStore (pScreen);

  /* KDrive does miDCInitialize right after miInitializeBackingStore */
  /* Setup the cursor routines */
#if CYGDEBUG
  winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n");
#endif
  miDCInitialize (pScreen, &g_winPointerCursorFuncs);

  /* KDrive does winCreateDefColormap right after miDCInitialize */
  /* Create a default colormap */
#if CYGDEBUG
  winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n");
#endif
  if (!winCreateDefColormap (pScreen))
    {
      ErrorF ("winFinishScreenInitFB - Could not create colormap\n");
      return FALSE;
    }

  /* Initialize the shadow framebuffer layer */
  if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
       || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
       || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
#ifdef XWIN_MULTIWINDOWEXTWM
      && !pScreenInfo->fMWExtWM
#endif
      )
    {
#if CYGDEBUG
      winDebug ("winFinishScreenInitFB - Calling shadowInit ()\n");
#endif
      if (!shadowInit (pScreen,
		       pScreenPriv->pwinShadowUpdate,
		       NULL))
	{
	  ErrorF ("winFinishScreenInitFB - shadowInit () failed\n");
	  return FALSE;
	}
    }

#ifdef XWIN_MULTIWINDOWEXTWM
  /* Handle multi-window external window manager mode */
  if (pScreenInfo->fMWExtWM)
    {
      winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n");
      
      RootlessInit(pScreen, &winMWExtWMProcs);
      
      winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n");
      
      rootless_CopyBytes_threshold = 0;
      rootless_FillBytes_threshold = 0;
      rootless_CompositePixels_threshold = 0;
      /* FIXME: How many? Profiling needed? */
      rootless_CopyWindow_threshold = 1;

      winWindowsWMExtensionInit ();
    }
#endif

  /* Handle rootless mode */
  if (pScreenInfo->fRootless)
    {
      /* Define the WRAP macro temporarily for local use */
#define WRAP(a) \
    if (pScreen->a) { \
        pScreenPriv->a = pScreen->a; \
    } else { \
        ErrorF("null screen fn " #a "\n"); \
        pScreenPriv->a = NULL; \
    }

      /* Save a pointer to each lower-level window procedure */
      WRAP(CreateWindow);
      WRAP(DestroyWindow);
      WRAP(RealizeWindow);
      WRAP(UnrealizeWindow);
      WRAP(PositionWindow);
      WRAP(ChangeWindowAttributes);
      WRAP(SetShape);

      /* Assign rootless window procedures to be top level procedures */
      pScreen->CreateWindow = winCreateWindowRootless;
      pScreen->DestroyWindow = winDestroyWindowRootless;
      pScreen->PositionWindow = winPositionWindowRootless;
      /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/
      pScreen->RealizeWindow = winMapWindowRootless;
      pScreen->UnrealizeWindow = winUnmapWindowRootless;
      pScreen->SetShape = winSetShapeRootless;

      /* Undefine the WRAP macro, as it is not needed elsewhere */
#undef WRAP
    }


#ifdef XWIN_MULTIWINDOW
  /* Handle multi window mode */
  else if (pScreenInfo->fMultiWindow)
    {
      /* Define the WRAP macro temporarily for local use */
#define WRAP(a) \
    if (pScreen->a) { \
        pScreenPriv->a = pScreen->a; \
    } else { \
        ErrorF("null screen fn " #a "\n"); \
        pScreenPriv->a = NULL; \
    }

      /* Save a pointer to each lower-level window procedure */
      WRAP(CreateWindow);
      WRAP(DestroyWindow);
      WRAP(RealizeWindow);
      WRAP(UnrealizeWindow);
      WRAP(PositionWindow);
      WRAP(ChangeWindowAttributes);
      WRAP(ReparentWindow);
      WRAP(RestackWindow);
      WRAP(ResizeWindow);
      WRAP(MoveWindow);
      WRAP(CopyWindow);
      WRAP(SetShape);

      /* Assign multi-window window procedures to be top level procedures */
      pScreen->CreateWindow = winCreateWindowMultiWindow;
      pScreen->DestroyWindow = winDestroyWindowMultiWindow;
      pScreen->PositionWindow = winPositionWindowMultiWindow;
      /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/
      pScreen->RealizeWindow = winMapWindowMultiWindow;
      pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
      pScreen->ReparentWindow = winReparentWindowMultiWindow;
      pScreen->RestackWindow = winRestackWindowMultiWindow;
      pScreen->ResizeWindow = winResizeWindowMultiWindow;
      pScreen->MoveWindow = winMoveWindowMultiWindow;
      pScreen->CopyWindow = winCopyWindowMultiWindow;
      pScreen->SetShape = winSetShapeMultiWindow;

      /* Undefine the WRAP macro, as it is not needed elsewhere */
#undef WRAP
    }
#endif

  /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */
  pScreenPriv->CloseScreen = pScreen->CloseScreen;
  pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;

#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
  /* Create a mutex for modules in separate threads to wait for */
  iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL);
  if (iReturn != 0)
    {
      ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
	      iReturn);
      return FALSE;
    }

  /* Own the mutex for modules in separate threads */
  iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted);
  if (iReturn != 0)
    {
      ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
	      iReturn);
      return FALSE;
    }

  /* Set the ServerStarted flag to false */
  pScreenPriv->fServerStarted = FALSE;
#endif

#ifdef XWIN_MULTIWINDOWEXTWM
  pScreenPriv->fRestacking = FALSE;
#endif

#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
  if (FALSE
#ifdef XWIN_MULTIWINDOW
      || pScreenInfo->fMultiWindow
#endif
#ifdef XWIN_MULTIWINDOWEXTWM
      || pScreenInfo->fInternalWM
#endif
      )
    { 
#if CYGDEBUG || YES
      winDebug ("winFinishScreenInitFB - Calling winInitWM.\n");
#endif

      /* Initialize multi window mode */
      if (!winInitWM (&pScreenPriv->pWMInfo,
		      &pScreenPriv->ptWMProc,
		      &pScreenPriv->ptXMsgProc,
		      &pScreenPriv->pmServerStarted,
		      pScreenInfo->dwScreen,
		      (HWND)&pScreenPriv->hwndScreen,
#ifdef XWIN_MULTIWINDOWEXTWM
		      pScreenInfo->fInternalWM ||
#endif
		      FALSE))
        {
          ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n");
          return FALSE;
        }
    }      
#endif

  /* Tell the server that we are enabled */
  pScreenPriv->fEnabled = TRUE;

  /* Tell the server that we have a valid depth */
  pScreenPriv->fBadDepth = FALSE;

#if CYGDEBUG || YES
  winDebug ("winFinishScreenInitFB - returning\n");
#endif

  return TRUE;
}
Пример #3
0
main(int argc, char *argv[])
{

	pthread_mutex_init(&lock, NULL);
	pthread_mutex_init(&atomic_lock, NULL);
	
	int i, j;
	struct timeval btv, etv;
	double delta, d1, d2;

	read_options(argc, argv);

	grp = (struct group *)malloc(sizeof(struct group) * ngroups);
	if(!grp)
	{
		perror("malloc");
		exit(1);
	}

	for(i = 0; i < ngroups; i++)
	{
		grp[i].tids = (struct thread *)malloc(sizeof(struct thread)*group_size);
		if (!grp[i].tids)
		{
			perror("malloc");
			exit(1);
		}
		memset(grp[i].tids, 0, sizeof(struct thread)*group_size);
		pthread_mutex_init(&grp[i].data_lock, NULL);
		grp[i].data = (unsigned int *)malloc(sizeof(unsigned int) * shared_data_size / sizeof(int));
		if(!grp[i].data)
		{
			perror("malloc");
			exit(1);
		}
	}

	pthread_t first_child;
	pthread_create(&first_child, NULL, boo, NULL);
	
	usleep(2*duration);
	
	pthread_join(first_child, NULL);
	for (i=0; i < ngroups; i++)
		for(j = 0; j < group_size; j++)
			pthread_join(grp[i].tids[j].tid, NULL);


	long int grp_count, tot_count;
	tot_count = 0;
	for(i = 0; i < ngroups; i++)
	{
		printf("group %d\n", i);
		grp_count = 0;
		for(j = 0; j < group_size; j++)
		{
			grp_count += grp[i].tids[j].loop_count;
			printf("thread %d: %ld\n", j, grp[i].tids[j].loop_count);
		}
		printf("total: %ld\n", grp_count);
		tot_count += grp_count;
		printf("\n");
	}	
	printf("Total count: %ld\n", tot_count);
	pthread_exit(NULL);
	/*d1 = etv.tv_sec + etv.tv_usec*1e-6;
	d2 = btv.tv_sec + btv.tv_usec*1e-6;

	delta = d1 - d2;

	printf ("Time taken = %f seconds \n", delta);
	*/
}
Пример #4
0
static __attribute__((constructor)) void
atomic_init(void)
{
	pthread_mutex_init(&atomic_mtx, NULL);
}
Пример #5
0
static void * seq_response(void * arg)
{
    prctl(PR_SET_NAME, "ccnfd_seq", 0, 0, 0);
    int sock;
    memcpy(&sock, (int * )arg, sizeof(int));
    free(arg);

    uint32_t payload_size;
    uint32_t name_len;
    char str[MAX_NAME_LENGTH];
    struct content_name * name = NULL;
    int chunks;
    int file_len;
    int rv = -1;
    struct segment seg;

    if (recv(sock, &payload_size, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "recv: %s.", strerror(errno));
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }

    if (recv(sock, &name_len, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "recv: %s.", strerror(errno));
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }

    if (name_len > MAX_NAME_LENGTH)
        name_len = MAX_NAME_LENGTH - 1;

    if (recv(sock, str, name_len, 0) == -1) {
        log_error(g_log, "recv: %s.", strerror(errno));
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }
    str[name_len] = '\0';

    if (recv(sock, &chunks, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "recv: %s.", strerror(errno));
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }

    if (recv(sock, &file_len, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "recv: %s.", strerror(errno));
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }

    name = content_name_create(str);

    /*
    if ((seg.obj = CS_getSegment(name)) != NULL) {
        log_error(g_log, "seq_response: found segment %s in CS", name->full_name);
        rv = 0;
        goto RETURN_CONTENT;
    }
    */

    log_print(g_log, "seq_response: retrieving %d chunks with base: %s",
              chunks, name->full_name);

    /* tell the broadcaster not to query the strategy layer to lower overhead */
    ccnfdnb_opt_t opts;
    opts.mode = 0;

    /* we add a dummy component of maximum length to make sure all the segment
     * names willl be valid.
     */
    snprintf(str, MAX_NAME_LENGTH - name->len - 1, "%d", chunks);
    if (content_name_appendComponent(name, str) != 0) {
        log_error(g_log, "could not append component to name (too long?)");
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }
    int chunk_size = (chunks > 1) ? ccnf_max_payload_size(name) : file_len;
    content_name_removeComponent(name, name->num_components - 1);

    completed_jobs_t dld_segments;
	pthread_mutex_init(&dld_segments.mutex, NULL);
	pthread_cond_init(&dld_segments.cond, NULL);
	dld_segments.completed = linked_list_init(free);

    seg.name = name;
    seg.num_chunks = chunks;
    seg.opts = &opts;
    seg.chunk_size = chunk_size - 1;
    seg.obj = malloc(sizeof(struct content_obj));
    seg.obj->name = name;
    seg.obj->data = malloc(file_len);
    if (!seg.obj->data) {
        log_error(g_log, "retrieve_segment: failed to allocated %d bytes!", file_len);
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }
    seg.obj->size = file_len;

    if ((rv = retrieve_segment(&seg)) < 0) {
        log_error(g_log, "retrieve_segment: failed to get %s!", name->full_name);
        send(sock, &rv, sizeof(uint32_t), 0);
        goto END_SEQ_RESP;
    }

    /* return the content */
    if (send(sock, &rv, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    if (send(sock, &seg.obj->publisher, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    if (send(sock, &name->len, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    if (send(sock, name->full_name, name_len, 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    if (send(sock, &seg.obj->timestamp, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    if (send(sock, &seg.obj->size, sizeof(uint32_t), 0) == -1) {
        log_error(g_log, "send: %s.", strerror(errno));
        goto END_SEQ_RESP;
    }

    int total = 0;
    int left = seg.obj->size;
    int n = -1;

    while (total < seg.obj->size) {
        log_debug(g_log, "total = %d", total);
        n = send(sock, seg.obj->data+total, left, 0);
        if (n == -1) break;
        total += n;
        left -= n;
        log_debug(g_log, "seq_response: sent %d bytes, %d bytes to go", n, left);
    }

    if (n == -1 || left != 0 || total != seg.obj->size) {
        log_error(g_log, "encountered error, sending segment, sent %d bytes!", total);
    } else {
        log_debug(g_log, "seq_response: returned %d bytes", total);
    }

    content_obj_destroy(seg.obj);

    END_SEQ_RESP:

    close(sock);

    return NULL;
}
Пример #6
0
int DissectInit(void)
{
    char tmp_dir[256];
    unsigned short i;
    NDPI_PROTOCOL_BITMASK all;

    /* part of file name */
    incr = 0;
    incr_dig = 0;

    /* info id */
    ppp_id = ProtId("ppp");
    eth_id = ProtId("eth");
    ip_id = ProtId("ip");
    ipv6_id = ProtId("ipv6");
    tcp_id = ProtId("tcp");
    if (ip_id != -1) {
        ip_dst_id = ProtAttrId(ip_id, "ip.dst");
        ip_src_id = ProtAttrId(ip_id, "ip.src");
        ip_offset_id = ProtAttrId(ip_id, "ip.offset");
    }
    if (ipv6_id != -1) {
        ipv6_dst_id = ProtAttrId(ipv6_id, "ipv6.dst");
        ipv6_src_id = ProtAttrId(ipv6_id, "ipv6.src");
        ipv6_offset_id = ProtAttrId(ipv6_id, "ipv6.offset");
    }
    if (tcp_id != -1) {
        port_dst_id = ProtAttrId(tcp_id, "tcp.dstport");
        port_src_id = ProtAttrId(tcp_id, "tcp.srcport");
        lost_id = ProtAttrId(tcp_id, "tcp.lost");
    }
    tcp_grb_id = ProtId("tcp-grb");
    
    /* pei id */
    pei_l7protocol_id = ProtPeiComptId(tcp_grb_id, "l7prot");
    pei_txt_id = ProtPeiComptId(tcp_grb_id, "txt");
    pei_size_id = ProtPeiComptId(tcp_grb_id, "size");
    pei_file_id = ProtPeiComptId(tcp_grb_id, "file");
    pei_file_type_id = ProtPeiComptId(tcp_grb_id, "ftype");

    /* tmp directory */
    sprintf(tmp_dir, "%s/%s", ProtTmpDir(), TCP_GRB_TMP_DIR);
    mkdir(tmp_dir, 0x01FF);

    /* init dig */
    if (enable_dig) {
        for (i=0; i!=dig_type_dim; i++) {
            if (!dig_tbl[i].sreg && dig_tbl[i].starttxt != NULL) {
                dig_tbl[i].start = strdup(dig_tbl[i].starttxt);
                if (dig_tbl[i].start == NULL) {
                    LogPrintf(LV_FATAL, "No memory!");
                    return -1;
                }
                dig_tbl[i].slen = TcpGrbDigConvert(dig_tbl[i].start);
            }
            if (!dig_tbl[i].ereg && dig_tbl[i].endtxt != NULL) {
                dig_tbl[i].end = strdup(dig_tbl[i].endtxt);
                if (dig_tbl[i].end == NULL) {
                    LogPrintf(LV_FATAL, "No memory!");
                    return -1;
                }
                dig_tbl[i].elen = TcpGrbDigConvert(dig_tbl[i].end);
            }
            //printf("File %s slen:%i elen: %i\n", dig_tbl[i].ename, dig_tbl[i].slen, dig_tbl[i].elen);
        }
    }

    /* ndpi */
    pthread_mutex_init(&ndpi_mux, NULL);
    ndpi = ndpi_init_detection_module(NDPI_TICK_RES, nDPImalloc, nDPIfree, nDPIPrintf);
    if (ndpi == NULL) {
        LogPrintf(LV_ERROR, "nDPi initializzation failed");

        return -1;
    }
    /* enable all protocols */
    NDPI_BITMASK_SET_ALL(all);
    ndpi_set_protocol_detection_bitmask2(ndpi, &all);
    ndpi_proto_size = ndpi_detection_get_sizeof_ndpi_id_struct();
    ndpi_flow_struct_size = ndpi_detection_get_sizeof_ndpi_flow_struct();

    return 0;
}
Пример #7
0
/******** Threads function *********/
void * threaded (void * arg)
{
	int me=(int)arg;
	pthread_mutex_t mtx;
	pthread_mutex_t * pmtx;
	pthread_mutexattr_t ma;
	pthread_mutexattr_t * pma;
	int ret;
#ifndef WITHOUT_XOPEN
	int sz = 2 + (sizeof(types) / sizeof(int));
#else
	int sz = 2;
#endif
	/* We will use mutex from the stack or from malloc'ed memory */
	char loc = ((me % 5) %2);
	
	if (loc)
	{
		pmtx = &mtx;
	}
	else
	{
		pmtx = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
		if (pmtx == NULL)
		{ UNRESOLVED(errno, "Memory allocation for mutex failed"); }
	}
	
	me %= sz;
	
	switch (me)
	{
		case 0: /* We will initialize the mutex with NULL pointer */
			pma = NULL;
			break;
		
		default: /* We will initialize the mutex with an attribute object */
			if ((ret = pthread_mutexattr_init(&ma)))
			{ UNRESOLVED(ret, "Mutex attribute init failed"); }
			pma = &ma;
			
			if (me == 1) 
				break;

			if ((ret = pthread_mutexattr_settype(&ma, types[me-2])))
			{ UNRESOLVED(ret, "Mutex attribute settype failed"); }
	}
	
	while (do_it)
	{
		ret = pthread_mutex_init(pmtx, pma);
		if (ret != 0)
		{ FAILED("Mutex init failed");	}
		/* We use the mutex to check everything is OK */
		ret = pthread_mutex_lock(pmtx);
		if (ret != 0)
		{ FAILED("Mutex lock failed");	}
		ret = pthread_mutex_unlock(pmtx);
		if (ret != 0)
		{ FAILED("Mutex unlock failed");	}
		ret = pthread_mutex_destroy(pmtx);
		if (ret != 0)
		{ FAILED("Mutex destroy failed");	}
	}
			
	if (!loc) /* mutex was malloc'ed */
		free(pmtx);
	
	if (me)
		if ((ret = pthread_mutexattr_destroy(pma)))
		{ FAILED("Mutex attribute destroy failed at the end"); }
		
	return NULL;
}
Пример #8
0
/*
 * Initializes the thread subsystem, creating various worker threads.
 *
 * nthreads  Number of worker event handler threads to spawn
 * main_base Event base for main thread
 */
void thread_init(int nthreads, struct event_base *main_base, void *(*join_request_listener_thread_routine)(void *), void *(*joining_thread_routine)(void *), void *(*node_removal_listener_thread_routine)(void *),void *(*node_propagation_thread_routine)(void *)) {
    int         i;
    int         power;

    pthread_mutex_init(&cache_lock, NULL);
    pthread_mutex_init(&stats_lock, NULL);

    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    pthread_mutex_init(&cqi_freelist_lock, NULL);
    cqi_freelist = NULL;


    /* Want a wide lock table, but don't waste memory */
    if (nthreads < 3) {
        power = 10;
    } else if (nthreads < 4) {
        power = 11;
    } else if (nthreads < 5) {
        power = 12;
    } else {
        /* 8192 buckets, and central locks don't scale much past 5 threads */
        power = 13;
    }

    item_lock_count = hashsize(power);

    item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t));
    if (! item_locks) {
        perror("Can't allocate item locks");
        exit(1);
    }
    for (i = 0; i < item_lock_count; i++) {
        pthread_mutex_init(&item_locks[i], NULL);
    }
    pthread_key_create(&item_lock_type_key, NULL);
    pthread_mutex_init(&item_global_lock, NULL);

    threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
    if (! threads) {
        perror("Can't allocate thread descriptors");
        exit(1);
    }

    dispatcher_thread.base = main_base;
    dispatcher_thread.thread_id = pthread_self();

    for (i = 0; i < nthreads; i++) {
        int fds[2];
        if (pipe(fds)) {
            perror("Can't create notify pipe");
            exit(1);
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        setup_thread(&threads[i]);
        /* Reserve three fds for the libevent base, and two for the pipe */
        stats.reserved_fds += 5;
    }

    /* Create threads after we've done all the libevent setup. */
    for (i = 0; i < nthreads; i++) {
        create_worker(worker_libevent, &threads[i]);
    }

    /* Wait for all the threads to set themselves up before returning. */
    pthread_mutex_lock(&init_lock);
    wait_for_thread_registration(nthreads);
    pthread_mutex_unlock(&init_lock);


    if(joining_thread_routine != NULL)
       connect_to_join_server(joining_thread_routine);
    else
        start_listening_on_join_port(join_request_listener_thread_routine);

    usleep(1000);
    start_listening_on_node_propagation_port(node_propagation_thread_routine);
    usleep(1000);
    start_listening_on_node_removal_port(node_removal_listener_thread_routine);

	///we may want to comment this
	pthread_join(connect_and_split_thread,NULL);
}
Пример #9
0
/*
 *  setup_session
 *
 *  Create a new session for the given handler
 */
void
setup_session(struct handler_args* hargs, 
    xmlHashTablePtr sessions, 
    struct qz_config* conf){ 

    struct session * this_session;

    // session_id is a number here, a string in the session struct,
    // and the encrypted contents of the session key, same value for each.
    uint64_t session_id;

    this_session = calloc(1, sizeof(struct session));

    // Assign a random number that has no zero octets 
    // as the session identifier, then test it.
    session_id = qzrandom64ch(this_session->session_id); 

    // There is a risk of session id collisions that
    // is larger than might be hoped from the 
    // birthday paradox.
    // With around 200 users, the chance of a hash key
    // collission is around 10^-15.  This is on the order
    // of random bit errors and cosmic ray bit flipping.
    // With around 6000 users, the chance goes up to
    // around 10^-6, or once in a million.
    // Or it could be the NSA is  messing with your PRNG, 
    // or it could be your  PRNG is setup wrong.
    // In any case, it is bad and wrong to continue.
    struct session* test_for_session;
    test_for_session = xmlHashLookup(sessions, this_session->session_id);

    if (test_for_session != NULL){
        fprintf(hargs->log, "%f %d %s:%d collision in session identifiers - %s\n",
            gettime(), hargs->request_id, __func__, __LINE__,
            "terminating application now");
        
       FCGX_FPrintF(hargs->err, 
           "collision in session identifiers - ending program now\n");

       exit(49);
    }

    if (pthread_mutex_init( &(this_session->session_lock), NULL) != 0){
        fprintf(hargs->log, "%f %d %s:%d mutex_init failed\n",
            gettime(), hargs->request_id, __func__, __LINE__);
        fflush(hargs->log);
        free(this_session);
        return;
    }

    make_etag(hargs->session_key, conf->tagger_socket_path, session_id);

    snprintf(this_session->tagger_socket_path, MAXPATHLEN, "%s", 
        conf->tagger_socket_path);  

    this_session->zero = 0;
    this_session->is_logged_in = false;
    this_session->logged_in_time = 0;
    this_session->logged_out_time = 0;
    this_session->last_activity_time = time(NULL);
    this_session->conn = NULL;
    
    // 197 is just an arbritrary value.
    // It is prime, hashes should be a prime size.
    // These should be in the config file. XXXXXXXXXXXXX
    this_session->opentables = xmlHashCreate(197);
    this_session->pgtype_datum = xmlHashCreate(197);
    this_session->form_tags = xmlHashCreate(197);
    this_session->form_sets = xmlHashCreate(197);

    this_session->integrity_token = conf->integrity_token;

    // index on session_id for crypto etag
    xmlHashAddEntry(sessions, this_session->session_id, this_session);

    // cookie path is /qz/ or whatever is used as the base path
    char* uri_parts[] = {hargs->uri_parts[0],"",NULL};
    char* path = build_path(uri_parts);

    make_cookie(hargs, "session_key", hargs->session_key, path,
        NULL, 0, false, true);
    free(path);

    hargs->session = this_session;

    fprintf(hargs->log, "%f %d %s:%d setup_session complete\n",
        gettime(), hargs->request_id, __func__, __LINE__);

    return;
}
Пример #10
0
void sna_vertex_init(struct sna *sna)
{
	pthread_mutex_init(&sna->render.lock, NULL);
	pthread_cond_init(&sna->render.wait, NULL);
	sna->render.active = 0;
}
Пример #11
0
/*
 * Initializes a connection queue.
 */
static void cq_init(CQ *cq) {
    pthread_mutex_init(&cq->lock, NULL);
    pthread_cond_init(&cq->cond, NULL);
    cq->head = NULL;
    cq->tail = NULL;
}
Пример #12
0
int adaptor_init(zhandle_t *zh)
{
    pthread_mutexattr_t recursive_mx_attr;
    struct adaptor_threads *adaptor_threads = calloc(1, sizeof(*adaptor_threads));
    if (!adaptor_threads) {
        LOG_ERROR(("Out of memory"));
        return -1;
    }

    /* We use a pipe for interrupting select() in unix/sol and socketpair in windows. */
#ifdef WIN32   
    if (create_socket_pair(adaptor_threads->self_pipe) == -1){
       LOG_ERROR(("Can't make a socket."));
#else
    if(pipe(adaptor_threads->self_pipe)==-1) {
        LOG_ERROR(("Can't make a pipe %d",errno));
#endif
        free(adaptor_threads);
        return -1;
    }
    set_nonblock(adaptor_threads->self_pipe[1]);
    set_nonblock(adaptor_threads->self_pipe[0]);

    pthread_mutex_init(&zh->auth_h.lock,0);

    zh->adaptor_priv = adaptor_threads;
    pthread_mutex_init(&zh->to_process.lock,0);
    pthread_mutex_init(&adaptor_threads->zh_lock,0);
    // to_send must be recursive mutex    
    pthread_mutexattr_init(&recursive_mx_attr);
    pthread_mutexattr_settype(&recursive_mx_attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&zh->to_send.lock,&recursive_mx_attr);
    pthread_mutexattr_destroy(&recursive_mx_attr);
    
    pthread_mutex_init(&zh->sent_requests.lock,0);
    pthread_cond_init(&zh->sent_requests.cond,0);
    pthread_mutex_init(&zh->completions_to_process.lock,0);
    pthread_cond_init(&zh->completions_to_process.cond,0);
    start_threads(zh);
    return 0;
}

void adaptor_finish(zhandle_t *zh)
{
    struct adaptor_threads *adaptor_threads;
    // make sure zh doesn't get destroyed until after we're done here
    api_prolog(zh); 
    adaptor_threads = zh->adaptor_priv;
    if(adaptor_threads==0) {
        api_epilog(zh,0);
        return;
    }

    if(!pthread_equal(adaptor_threads->io,pthread_self())){
        wakeup_io_thread(zh);
        pthread_join(adaptor_threads->io, 0);
    }else
        pthread_detach(adaptor_threads->io);
    
    if(!pthread_equal(adaptor_threads->completion,pthread_self())){
        pthread_mutex_lock(&zh->completions_to_process.lock);
        pthread_cond_broadcast(&zh->completions_to_process.cond);
        pthread_mutex_unlock(&zh->completions_to_process.lock);
        pthread_join(adaptor_threads->completion, 0);
    }else
        pthread_detach(adaptor_threads->completion);
    
    api_epilog(zh,0);
}

void adaptor_destroy(zhandle_t *zh)
{
    struct adaptor_threads *adaptor = zh->adaptor_priv;
    if(adaptor==0) return;
    
    pthread_cond_destroy(&adaptor->cond);
    pthread_mutex_destroy(&adaptor->lock);
    pthread_mutex_destroy(&zh->to_process.lock);
    pthread_mutex_destroy(&zh->to_send.lock);
    pthread_mutex_destroy(&zh->sent_requests.lock);
    pthread_cond_destroy(&zh->sent_requests.cond);
    pthread_mutex_destroy(&zh->completions_to_process.lock);
    pthread_cond_destroy(&zh->completions_to_process.cond);
    pthread_mutex_destroy(&adaptor->zh_lock);

    pthread_mutex_destroy(&zh->auth_h.lock);

    close(adaptor->self_pipe[0]);
    close(adaptor->self_pipe[1]);
    free(adaptor);
    zh->adaptor_priv=0;
}

int wakeup_io_thread(zhandle_t *zh)
{
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
    char c=0;
#ifndef WIN32
    return write(adaptor_threads->self_pipe[1],&c,1)==1? ZOK: ZSYSTEMERROR;    
#else
    return send(adaptor_threads->self_pipe[1], &c, 1, 0)==1? ZOK: ZSYSTEMERROR;    
#endif         
}

int adaptor_send_queue(zhandle_t *zh, int timeout)
{
    if(!zh->close_requested)
        return wakeup_io_thread(zh);
    // don't rely on the IO thread to send the messages if the app has
    // requested to close 
    return flush_send_queue(zh, timeout);
}

/* These two are declared here because we will run the event loop
 * and not the client */
#ifdef WIN32
int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
        struct timeval *tv);
#else
int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
        struct timeval *tv);
#endif
int zookeeper_process(zhandle_t *zh, int events);

#ifdef WIN32
unsigned __stdcall do_io( void * v)
#else
void *do_io(void *v)
#endif
{
    zhandle_t *zh = (zhandle_t*)v;
#ifndef WIN32
    struct pollfd fds[2];
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;

    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started IO thread"));
    fds[0].fd=adaptor_threads->self_pipe[0];
    fds[0].events=POLLIN;
    while(!zh->close_requested) {
        struct timeval tv;
        int fd;
        int interest;
        int timeout;
        int maxfd=1;
        int rc;
        
        zookeeper_interest(zh, &fd, &interest, &tv);
        if (fd != -1) {
            fds[1].fd=fd;
            fds[1].events=(interest&ZOOKEEPER_READ)?POLLIN:0;
            fds[1].events|=(interest&ZOOKEEPER_WRITE)?POLLOUT:0;
            maxfd=2;
        }
        timeout=tv.tv_sec * 1000 + (tv.tv_usec/1000);
        
        poll(fds,maxfd,timeout);
        if (fd != -1) {
            interest=(fds[1].revents&POLLIN)?ZOOKEEPER_READ:0;
            interest|=((fds[1].revents&POLLOUT)||(fds[1].revents&POLLHUP))?ZOOKEEPER_WRITE:0;
        }
        if(fds[0].revents&POLLIN){
            // flush the pipe
            char b[128];
            while(read(adaptor_threads->self_pipe[0],b,sizeof(b))==sizeof(b)){}
        }        
#else
    fd_set rfds, wfds, efds;
    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started IO thread"));
    FD_ZERO(&rfds);   FD_ZERO(&wfds);    FD_ZERO(&efds);
    while(!zh->close_requested) {      
        struct timeval tv;
        SOCKET fd;
        SOCKET maxfd=adaptor_threads->self_pipe[0];
        int interest;        
        int rc;
               
       zookeeper_interest(zh, &fd, &interest, &tv);
       if (fd != -1) {
           if (interest&ZOOKEEPER_READ) {
                FD_SET(fd, &rfds);
            } else {
                FD_CLR(fd, &rfds);
            }
           if (interest&ZOOKEEPER_WRITE) {
                FD_SET(fd, &wfds);
            } else {
                FD_CLR(fd, &wfds);
            }                  
        }
       FD_SET( adaptor_threads->self_pipe[0] ,&rfds );        
       rc = select((int)maxfd, &rfds, &wfds, &efds, &tv);
       if (fd != -1) 
       {
           interest = (FD_ISSET(fd, &rfds))? ZOOKEEPER_READ:0;
           interest|= (FD_ISSET(fd, &wfds))? ZOOKEEPER_WRITE:0;
        }
               
       if (FD_ISSET(adaptor_threads->self_pipe[0], &rfds)){
            // flush the pipe/socket
            char b[128];
           while(recv(adaptor_threads->self_pipe[0],b,sizeof(b), 0)==sizeof(b)){}
       }
#endif
        // dispatch zookeeper events
        rc = zookeeper_process(zh, interest);
        // check the current state of the zhandle and terminate 
        // if it is_unrecoverable()
        if(is_unrecoverable(zh))
            break;
    }
    api_epilog(zh, 0);    
    LOG_DEBUG(("IO thread terminated"));
    return 0;
}

#ifdef WIN32
unsigned __stdcall do_completion( void * v)
#else
void *do_completion(void *v)
#endif
{
    zhandle_t *zh = v;
    api_prolog(zh);
    notify_thread_ready(zh);
    LOG_DEBUG(("started completion thread"));
    while(!zh->close_requested) {
        pthread_mutex_lock(&zh->completions_to_process.lock);
        while(!zh->completions_to_process.head && !zh->close_requested) {
            pthread_cond_wait(&zh->completions_to_process.cond, &zh->completions_to_process.lock);
        }
        pthread_mutex_unlock(&zh->completions_to_process.lock);
        process_completions(zh);
    }
    api_epilog(zh, 0);    
    LOG_DEBUG(("completion thread terminated"));
    return 0;
}
Пример #13
0
/**
 * \brief Initialize verse client context
 */
int vc_init_ctx(struct VC_CTX *vc_ctx)
{
	int i;

	/* Allocate memory for session slots and make session slots NULL */
	vc_ctx->vsessions = (struct VSession**)malloc(sizeof(struct VSession*)*vc_ctx->max_sessions);
	vc_ctx->session_counter = 0;
	for(i=0; i<vc_ctx->max_sessions; i++) {
		vc_ctx->vsessions[i] = NULL;
	}
	/* Initialize callback function */
	vc_init_func_storage(&vc_ctx->vfs);

#ifdef WITH_OPENSSL
	/* Set up the library */
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

	/* Set up SSL context for TLS */
	if( (vc_ctx->tls_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX for TLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* Load the trust store for TLS */
	if(SSL_CTX_load_verify_locations(vc_ctx->tls_ctx, NULL, vc_ctx->ca_path) != 1) {
		v_print_log(VRS_PRINT_ERROR, "Loading path with CA certificates failed.\n");
		ERR_print_errors_fp(v_log_file());
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Path %s with CA certificates loaded successfully.\n",
				vc_ctx->ca_path);
	}
#endif

#if (defined WITH_OPENSSL) && OPENSSL_VERSION_NUMBER>=0x10000000
	/* Set up SSL context for DTSL */
	if( (vc_ctx->dtls_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* Load the trust store for DTLS */
	if(SSL_CTX_load_verify_locations(vc_ctx->dtls_ctx, NULL, vc_ctx->ca_path) != 1) {
		v_print_log(VRS_PRINT_ERROR, "Loading path with CA certificates failed.\n");
		ERR_print_errors_fp(v_log_file());
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Path %s with CA certificates loaded successfully.\n",
				vc_ctx->ca_path);
	}

	/* Negotiate ciphers with server
	 * For testing: (encryption:none, mac:sha) eNULL:!MDP5
	 * For real use: ALL:ALL */
	if( SSL_CTX_set_cipher_list(vc_ctx->dtls_ctx, "eNULL:!MD5") == 0) {
		v_print_log(VRS_PRINT_ERROR, "Setting ciphers for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* This is necessary for DTLS */
	SSL_CTX_set_read_ahead(vc_ctx->dtls_ctx, 1);
#else
	vc_ctx->dtls_ctx = NULL;
#endif

	/* Default name and version */
	vc_ctx->client_name = NULL;
	vc_ctx->client_version = NULL;

	pthread_mutex_init(&vc_ctx->mutex, NULL);

	return 1;
}
Пример #14
0
void _thread_mutex_init(pthread_mutex_t* down_mutex) {
	pthread_mutex_init(down_mutex, NULL);
}
Пример #15
0
/** Initializes a read file structure.
 *  Clears a new read file structure, copies the file path, sets the record
 *  size, and sets up its thread mutex.
 *
 *  @param[in] file                 The file structure.
 *  @param[in] records_per_block    The number of records per block.
 *  @param[in] start                Start string.
 *  @param[in] end                  End string.
 *  @param[in] alphabet             Alphabet string to use.
 */
int brute_force_init(file_st *file, int records_per_block, char *start,
                     char *end, char *alphabet) {
    brute_force_data_st *bf_st;
    size_t start_len;
    size_t end_len;
    size_t alp_len;
    int i;

    start_len = strlen(start);
    end_len = strlen(end);
    alp_len = strlen(alphabet);

    /* Start can not be longer than end */
    if (start_len > end_len) {
        errno = EINVAL;
        return E_ATTK_SYSTEM;
    }

    /* Every character in start must be in the alphabet */
    for (i = 0; i < start_len; i++) {
        if (char_index(alphabet, alp_len, start + i) == NULL) {
            errno = EINVAL;
            return E_ATTK_SYSTEM;
        }
    }

    /* Every character in end must be in the alphabet */
    for (i = 0; i < end_len; i++) {
        if (char_index(alphabet, alp_len, end + i) == NULL) {
            errno = EINVAL;
            return E_ATTK_SYSTEM;
        }
    }

    /* If they are the same size, start can not be greater than end */
    if (start_len == end_len) {
        for (i = 0; i < start_len; i++) {
            if (char_index(alphabet, alp_len, start + i)
                   > char_index(alphabet, alp_len, end + i)) {
                errno = EINVAL;
                return E_ATTK_SYSTEM;
            }
            if (char_index(alphabet, alp_len, start + i)
                < char_index(alphabet, alp_len, end + i)) {
                break;
            }
        }
    }

    /* Clear the structure */
    memset(file, 0, sizeof(file_st));

    /* Set defaults */
    file->record_size = strlen(end) + 1;
    file->records_per_block = records_per_block;

    /* Initialize pthread objects */
    pthread_mutex_init(&(file->mut), NULL);

    /* Create brute_force_data_st */
    bf_st = malloc(sizeof(brute_force_data_st));
    file->file_data = bf_st;

    /* Create buffers */
    bf_st->start = malloc(strlen(start) + 1);
    bf_st->end = malloc(strlen(end) + 1);
    bf_st->alphabet = malloc(strlen(alphabet) + 1);
    bf_st->last = malloc(strlen(end) + 1);
    memset(bf_st->start, 0, strlen(start) + 1);
    memset(bf_st->end, 0, strlen(end) + 1);
    memset(bf_st->alphabet, 0, strlen(alphabet) + 1);
    memset(bf_st->last, 0, strlen(end) + 1);

    /* Fill buffers */
    memcpy(bf_st->start, start, strlen(start));
    memcpy(bf_st->end, end, strlen(end));
    memcpy(bf_st->alphabet, alphabet, strlen(alphabet));

    /* Setup class methods */
    file->open_file = bf_open_file;
    file->next_block = bf_next_block;
    file->free_block = bf_free_block;
    file->close_file = bf_close_file;

    return 0;
}
Пример #16
0
/****************************************************************************
*
*						Subroutine main
*
*****************************************************************************/
int main(int argc, char *argv[])
{
	int tlkilled,tlpid, rc,status;  /*tlpid=trace logger pid */
	struct traceparser_state * tp_state;
	char message[200];
	pthread_t cur_thread;

	/*
	 * Start the tests.
	 */
	teststart(argv[0]);
 
	/* Get rid of tracelogger if it is running  */
	tlkilled=kill_tl();
	/* Setup a channel for the MsgSend Events */
	chid=ChannelCreate(0);
	assert(chid!=-1);

	mypid=getpid();
	
	/* Setup the barrier used to syncronize */
	pthread_barrier_init(&global_barrier, NULL, 2);

	/* Setup the mutex for the mutex/condvar state test */
	rc=pthread_mutex_init(&mymutex,NULL);	
	assert(rc==EOK);

	/* Setup the condvar for the condvar state test */
	rc=pthread_cond_init(&mycondvar,NULL);	
	assert(rc==EOK);

	/* setup the sem tfor the sem state test */
	rc=sem_init(&mysem, 0,0);
	assert(rc==0);

	/* Get io-privity */
	rc=ThreadCtl( _NTO_TCTL_IO, 0 );
	assert(rc!=-1);

	/* Setup the needed child */
	child_pid=fork();
	assert(child_pid!=-1);
	if (child_pid==0) {
		/* This child is used only in the stopped state test.
 		 * it will just sit and loop
		 */
		while (1) {
			delay(10);
		}
		exit(0);
	}
	/* and create a thread to go into various states */
	rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
	assert(rc==EOK);
	for (cur_state=STATE_DEAD;cur_state<=STATE_SEM;cur_state++) {
		/* these states can not be reliably and or safely triggered. */
		if ((cur_state==STATE_STACK) || (cur_state==STATE_WAITPAGE) || cur_state==STATE_INTR)
			continue;
		/***********************************************************************/
	
		/***********************************************************************/
		/*
		 * Make sure that if we trigger a thread state, that it gets logged
		 * properly (all the information in the tracelogger is correct)
		 * This tests the information provided in wide mode.
		 */
		snprintf(message, sizeof(message),"%s in wide mode", state_str[cur_state]);
	 	testpntbegin(message);

		correct_values_eh=0;
		exp_thread=cur_thread;
			
		/* We need to start up the tracelogger in daemon mode, 1 itteration.
		 * we will filter out everything other then thread states, then 
		 * start logging. 
		 * We then will trigger a thread state change, and flush the trace buffer. 
		 * This  should create a VERY minimal trace buffer that will be easily parsed
		 */
		tlpid=start_logger();
		sleep(1);
		/* Set the logger to wide emmiting mode */
		rc=TraceEvent(_NTO_TRACE_SETALLCLASSESWIDE);
		assert(rc!=-1);
		fast_mode=WIDE;
		/* Add the given thread event in the thread class back in */
		rc=TraceEvent(_NTO_TRACE_ADDEVENT, _NTO_TRACE_THREAD,(1<<cur_state));
		assert(rc!=-1);
		/* Filter out all tids other then the state_thread */
		if  (cur_state==STATE_STOPPED) {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, child_pid, 1);
		} else {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, getpid(),cur_thread);
		}
		assert(rc!=-1);

		/* Setup the event handler */
		memset(&my_event_data, 0, sizeof(my_event_data));
		memset(data_array, 0, sizeof(data_array));
		my_event_data.data_array=data_array;
		rc=TraceEvent(_NTO_TRACE_ADDEVENTHANDLER, _NTO_TRACE_THREAD,(1<<cur_state), event_handler, &my_event_data);
		assert(rc!=-1);


		/* then trigger an event.  Logging is started inside the state thread
		 * right before it tries to trigger the given state.
		 * the two barrier waits are to 
		 * 1) Tell the state thread that everything is setup so it should trigger the event
		 * 2) Wait for the state thread to tell us it has finished.
		 */
		pthread_barrier_wait(&global_barrier);

		if ((cur_state==STATE_SEND)|| (cur_state==STATE_REPLY)) {
			/* If the thread is going into the send state, we should receive and reply */
			sleep(1);
			status=MsgReceive(chid, message, sizeof(message), NULL);
			MsgReply(status, EOK, "ok", 3);
		} else if (cur_state==STATE_RECEIVE) {
			/* If the thread is going to call reveive, we should send it a message */
			sleep(1);
			status=ConnectAttach(0, getpid(), chid, _NTO_SIDE_CHANNEL, 0);
			MsgSend(status, message, 10, message,10);
		} else if (cur_state==STATE_MUTEX) {
			pthread_mutex_lock(&mymutex);
			sleep(2);
			pthread_mutex_unlock(&mymutex);
		} else if (cur_state==STATE_CONDVAR) {
			sleep(2);
			pthread_cond_signal(&mycondvar);
		} else if (cur_state==STATE_SEM) {
			sleep(2);
			sem_post(&mysem);
		}
		
		
		/* If the state thread is going to try to trigger the dead state, it will have to
		 * exit, so we can not expect it to call barrier_wait to tell us it's done. 
		 */
		if ((1<<cur_state)!=_NTO_TRACE_THDEAD) {
			pthread_barrier_wait(&global_barrier);
		} else {
			/* If the state thread is going to exit, then we should just
 			 * give it time to exit, then restart it.
			 */
			sleep(2); 
			rc=pthread_join(cur_thread, (void **)&status);
			assert(rc==EOK);
			rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
		}
		delay(100);
		
		/* flush the trace buffer and wait for the tracelogger to exit*/
		rc=TraceEvent(_NTO_TRACE_FLUSHBUFFER);	
		assert(rc!=-1);
		rc=waitpid(tlpid, &status, 0);
		assert(tlpid==rc);
	
		/* Now, setup the traceparser lib to pull out the thread state events, 
		 * and make sure our event shows up 
		 */
		tp_state=traceparser_init(NULL);
		assert(tp_state!=NULL);
		traceparser_cs(tp_state, NULL, parse_cb, _NTO_TRACE_THREAD, (1<<cur_state));
	
		/* Since we don't want a bunch of output being displayed in the 
		 * middle of the tests, turn off verbose output.
		 */
		traceparser_debug(tp_state, stdout, _TRACEPARSER_DEBUG_NONE);
		/* Set correct_values to 0, so we can see if the callback actually
		 * got called. 
		 */
		correct_values=0;
		/* And parse the tracebuffer */
		traceparser(tp_state, NULL, "/dev/shmem/tracebuffer");
		
		if (correct_values==0) 
			testpntfail("Our callback never got called, no events?");
		else if (correct_values==-1)
			testpntfail("Got the wrong thread state");
		else if (correct_values==-2) 
			testpntfail("Got the wrong pid");
		else if (correct_values==-3)
			testpntfail("Got the wrong tid");
		else if (correct_values_eh<-1)
			testpntfail("Got bad values in the event handler");
		else if (correct_values_eh==0)
			testpntfail("Event handler not called");
		else if (correct_values_eh==1)
			testpntpass("Good");
		else {
			snprintf(message,sizeof(message),"correct_values_eh : %d",correct_values_eh);
			testnote(message);
		snprintf(message,sizeof(message),"correct_values : %d",correct_values);
		testnote(message);	
			testpntfail("This should not happen");
			}
		traceparser_destroy(&tp_state);
	 	testpntend();
		/***********************************************************************/
	
		/***********************************************************************/
		/*
		 * Make sure that if we trigger a thread state, that it gets logged
		 * properly (all the information in the tracelogger is correct)
		 * This tests the information provided in fast mode.
		 */
		snprintf(message, sizeof(message),"%s in fast mode", state_str[cur_state]);
	 	testpntbegin(message);

		correct_values_eh=0;
		exp_thread=cur_thread;
			
		/* We need to start up the tracelogger in daemon mode, 1 itteration.
		 * we will filter out everything other then thread states, then 
		 * start logging. 
		 * We then will trigger a thread state change, and flush the trace buffer. 
		 * This  should create a VERY minimal trace buffer that will be easily parsed
		 */
		tlpid=start_logger();
		sleep(1);
		/* Set the logger to fast emmiting mode */
		rc=TraceEvent(_NTO_TRACE_SETALLCLASSESFAST);
		assert(rc!=-1);
		fast_mode=FAST;
		/* Add the given thread event in the thread class back in */
		rc=TraceEvent(_NTO_TRACE_ADDEVENT, _NTO_TRACE_THREAD,(1<<cur_state));
		assert(rc!=-1);
		/* Filter out all tids other then the state_thread */
		if  (cur_state==STATE_STOPPED) {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, child_pid, 1);
		} else {
			rc=TraceEvent(_NTO_TRACE_SETCLASSTID, _NTO_TRACE_THREAD, getpid(),cur_thread);
		}
		assert(rc!=-1);

		/* Setup the event handler */
		memset(&my_event_data, 0, sizeof(my_event_data));
		memset(data_array, 0, sizeof(data_array));
		my_event_data.data_array=data_array;
		rc=TraceEvent(_NTO_TRACE_ADDEVENTHANDLER, _NTO_TRACE_THREAD,(1<<cur_state), event_handler, &my_event_data);
		assert(rc!=-1);


		/* then trigger an event.  Logging is started inside the state thread
		 * right before it tries to trigger the given state.
		 * the two barrier waits are to 
		 * 1) Tell the state thread that everything is setup so it should trigger the event
		 * 2) Wait for the state thread to tell us it has finished.
		 */
		pthread_barrier_wait(&global_barrier);

		if ((cur_state==STATE_SEND)|| (cur_state==STATE_REPLY)) {
			/* If the thread is going into the send state, we should receive and reply */
			sleep(1);
			status=MsgReceive(chid, message, sizeof(message), NULL);
			MsgReply(status, EOK, "ok", 3);
		} else if (cur_state==STATE_RECEIVE) {
			/* If the thread is going to call reveive, we should send it a message */
			sleep(1);
			status=ConnectAttach(0, getpid(), chid, _NTO_SIDE_CHANNEL, 0);
			MsgSend(status, message, 10, message,10);
		} else if (cur_state==STATE_MUTEX) {
			pthread_mutex_lock(&mymutex);
			sleep(2);
			pthread_mutex_unlock(&mymutex);
		} else if (cur_state==STATE_CONDVAR) {
			sleep(2);
			pthread_cond_signal(&mycondvar);
		} else if (cur_state==STATE_SEM) {
			sleep(2);
			sem_post(&mysem);
		}
		
		
		/* If the state thread is going to try to trigger the dead state, it will have to
		 * exit, so we can not expect it to call barrier_wait to tell us it's done. 
		 */
		if ((1<<cur_state)!=_NTO_TRACE_THDEAD) {
			pthread_barrier_wait(&global_barrier);
		} else {
			/* If the state thread is going to exit, then we should just
 			 * give it time to exit, then restart it.
			 */
			sleep(2); 
			rc=pthread_join(cur_thread, (void **)&status);
			assert(rc==EOK);
			rc=pthread_create(&cur_thread, NULL, state_thread, NULL);
		}
		delay(100);
		
		/* flush the trace buffer and wait for the tracelogger to exit*/
		rc=TraceEvent(_NTO_TRACE_FLUSHBUFFER);	
		assert(rc!=-1);
		rc=waitpid(tlpid, &status, 0);
		assert(tlpid==rc);
	
		/* Now, setup the traceparser lib to pull out the thread state events, 
		 * and make sure our event shows up 
		 */
		tp_state=traceparser_init(NULL);
		assert(tp_state!=NULL);
		traceparser_cs(tp_state, NULL, parse_cb, _NTO_TRACE_THREAD, (1<<cur_state));
	
		/* Since we don't want a bunch of output being displayed in the 
		 * middle of the tests, turn off verbose output.
		 */
		traceparser_debug(tp_state, stdout, _TRACEPARSER_DEBUG_NONE);
		/* Set correct_values to 0, so we can see if the callback actually
		 * got called. 
		 */
		correct_values=0;
		/* And parse the tracebuffer */
		traceparser(tp_state, NULL, "/dev/shmem/tracebuffer");
		
		if (correct_values==0) 
			testpntfail("Our callback never got called, no events?");
		else if (correct_values==-1)
			testpntfail("Got the wrong thread state");
		else if (correct_values==-2) 
			testpntfail("Got the wrong pid");
		else if (correct_values==-3)
			testpntfail("Got the wrong tid");
		else if (correct_values_eh<-1)
			testpntfail("Got bad values in the event handler");
		else if (correct_values_eh==0)
			testpntfail("Event handler not called");
		else if (correct_values_eh==1)
			testpntpass("Good");
		else 
			testpntfail("This should not happen");

		traceparser_destroy(&tp_state);
	 	testpntend();
		/***********************************************************************/

	}
	/* If the tracelogger was running when we started, we should restart it again */
	if (tlkilled==1) 
		system("reopen /dev/null ; tracelogger -n 0 -f /dev/null &");
	/* Kill off the child we had forked earler */
	kill (child_pid, SIGKILL);
	teststop(argv[0]);
	return 0;
}
Пример #17
0
/*
 *	Allocate the thread pool, and seed it with an initial number
 *	of threads.
 *
 *	FIXME: What to do on a SIGHUP???
 */
int thread_pool_init(CONF_SECTION *cs, int *spawn_flag)
{
#ifndef WITH_GCD
	int		i, rcode;
	CONF_SECTION	*pool_cf;
#endif
	time_t		now;

	cs = cs;		/* -Wunused */

	now = time(NULL);

	rad_assert(spawn_flag != NULL);
	rad_assert(*spawn_flag == TRUE);
	rad_assert(pool_initialized == FALSE); /* not called on HUP */

#ifndef WITH_GCD
	pool_cf = cf_subsection_find_next(cs, NULL, "thread");
	if (!pool_cf) *spawn_flag = FALSE;
#endif

	/*
	 *	Initialize the thread pool to some reasonable values.
	 */
	memset(&thread_pool, 0, sizeof(THREAD_POOL));
#ifndef WITH_GCD
	thread_pool.head = NULL;
	thread_pool.tail = NULL;
	thread_pool.total_threads = 0;
	thread_pool.max_thread_num = 1;
	thread_pool.cleanup_delay = 5;
#endif
	thread_pool.spawn_flag = *spawn_flag;
	
	/*
	 *	Don't bother initializing the mutexes or
	 *	creating the hash tables.  They won't be used.
	 */
	if (!*spawn_flag) return 0;
	
#ifdef WNOHANG
	if ((pthread_mutex_init(&thread_pool.wait_mutex,NULL) != 0)) {
		radlog(L_ERR, "FATAL: Failed to initialize wait mutex: %s",
		       strerror(errno));
		return -1;
	}
	
	/*
	 *	Create the hash table of child PID's
	 */
	thread_pool.waiters = fr_hash_table_create(pid_hash,
						   pid_cmp,
						   free);
	if (!thread_pool.waiters) {
		radlog(L_ERR, "FATAL: Failed to set up wait hash");
		return -1;
	}
#endif

#ifndef WITH_GCD
	if (cf_section_parse(pool_cf, NULL, thread_config) < 0) {
		return -1;
	}

	/*
	 *	Catch corner cases.
	 */
	if (thread_pool.min_spare_threads < 1)
		thread_pool.min_spare_threads = 1;
	if (thread_pool.max_spare_threads < 1)
		thread_pool.max_spare_threads = 1;
	if (thread_pool.max_spare_threads < thread_pool.min_spare_threads)
		thread_pool.max_spare_threads = thread_pool.min_spare_threads;
	if (thread_pool.max_threads == 0)
		thread_pool.max_threads = 256;
#endif	/* WITH_GCD */

	/*
	 *	The pool has already been initialized.  Don't spawn
	 *	new threads, and don't forget about forked children,
	 */
	if (pool_initialized) {
		return 0;
	}

#ifndef WITH_GCD
	/*
	 *	Initialize the queue of requests.
	 */
	memset(&thread_pool.semaphore, 0, sizeof(thread_pool.semaphore));
	rcode = sem_init(&thread_pool.semaphore, 0, SEMAPHORE_LOCKED);
	if (rcode != 0) {
		radlog(L_ERR, "FATAL: Failed to initialize semaphore: %s",
		       strerror(errno));
		return -1;
	}

	rcode = pthread_mutex_init(&thread_pool.queue_mutex,NULL);
	if (rcode != 0) {
		radlog(L_ERR, "FATAL: Failed to initialize queue mutex: %s",
		       strerror(errno));
		return -1;
	}

	/*
	 *	Allocate multiple fifos.
	 */
	for (i = 0; i < RAD_LISTEN_MAX; i++) {
		int num = mainconfig.max_requests;

		if (!num || (num > 65536)) num = 65536;
		thread_pool.fifo[i] = fr_fifo_create(num, NULL);
		if (!thread_pool.fifo[i]) {
			radlog(L_ERR, "FATAL: Failed to set up request fifo");
			return -1;
		}
	}
#endif

#ifdef HAVE_OPENSSL_CRYPTO_H
	/*
	 *	If we're linking with OpenSSL too, then we need
	 *	to set up the mutexes and enable the thread callbacks.
	 */
	if (!setup_ssl_mutexes()) {
		radlog(L_ERR, "FATAL: Failed to set up SSL mutexes");
		return -1;
	}
#endif


#ifndef WITH_GCD
	/*
	 *	Create a number of waiting threads.
	 *
	 *	If we fail while creating them, do something intelligent.
	 */
	for (i = 0; i < thread_pool.start_threads; i++) {
		if (spawn_thread(now, 0) == NULL) {
			return -1;
		}
	}
#else
	thread_pool.queue = dispatch_queue_create("org.freeradius.threads", NULL);
	if (!thread_pool.queue) {
		radlog(L_ERR, "Failed creating dispatch queue: %s\n",
		       strerror(errno));
		exit(1);
	}
#endif

	DEBUG2("Thread pool initialized");
	pool_initialized = TRUE;
	return 0;
}
Пример #18
0
//int main(int argc, const char * argv[]) {
void VoxelServer::run() {
    
    const char VOXEL_SERVER_LOGGING_TARGET_NAME[] = "voxel-server";
    
    // change the logging target name while this is running
    Logging::setTargetName(VOXEL_SERVER_LOGGING_TARGET_NAME);

    // Now would be a good time to parse our arguments, if we got them as assignment
    if (getNumPayloadBytes() > 0) {
        parsePayload();
    }

    pthread_mutex_init(&_treeLock, NULL);
    
    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    const char* JURISDICTION_FILE = "--jurisdictionFile";
    const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
    if (jurisdictionFile) {
        qDebug("jurisdictionFile=%s\n", jurisdictionFile);

        qDebug("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
        _jurisdiction = new JurisdictionMap(jurisdictionFile);
        qDebug("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
    } else {
        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
        const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
        if (jurisdictionRoot) {
            qDebug("jurisdictionRoot=%s\n", jurisdictionRoot);
        }

        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
        const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
        if (jurisdictionEndNodes) {
            qDebug("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
        }

        if (jurisdictionRoot || jurisdictionEndNodes) {
            _jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
        }
    }

    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
    _dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
    qDebug("dumpVoxelsOnMove=%s\n", debug::valueOf(_dumpVoxelsOnMove));
    
    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
    bool dontSendEnvironments =  getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
    if (dontSendEnvironments) {
        qDebug("Sending environments suppressed...\n");
        _sendEnvironments = false;
    } else { 
        // should we send environments? Default is yes, but this command line suppresses sending
        const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
        _sendMinimalEnvironment =  getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
        qDebug("Using Minimal Environment=%s\n", debug::valueOf(_sendMinimalEnvironment));
    }
    qDebug("Sending environments=%s\n", debug::valueOf(_sendEnvironments));
    
    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
    
    setvbuf(stdout, NULL, _IOLBF, 0);

    // tell our NodeList about our desire to get notifications
    nodeList->addHook(&_nodeWatcher);
    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;

    nodeList->startSilentNodeRemovalThread();
    srand((unsigned)time(0));
    
    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
    _displayVoxelStats =  getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
    qDebug("displayVoxelStats=%s\n", debug::valueOf(_displayVoxelStats));

    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
    _debugVoxelSending =  getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
    qDebug("debugVoxelSending=%s\n", debug::valueOf(_debugVoxelSending));

    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
    _debugVoxelReceiving =  getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
    qDebug("debugVoxelReceiving=%s\n", debug::valueOf(_debugVoxelReceiving));

    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
    _shouldShowAnimationDebug =  getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
    qDebug("shouldShowAnimationDebug=%s\n", debug::valueOf(_shouldShowAnimationDebug));

    // By default we will voxel persist, if you want to disable this, then pass in this parameter
    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
    if (getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
        _wantVoxelPersist = false;
    }
    qDebug("wantVoxelPersist=%s\n", debug::valueOf(_wantVoxelPersist));

    // if we want Voxel Persistence, load the local file now...
    bool persistantFileRead = false;
    if (_wantVoxelPersist) {

        // Check to see if the user passed in a command line option for setting packet send rate
        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
        const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
        if (voxelsPersistFilenameParameter) {
            strcpy(_voxelPersistFilename, voxelsPersistFilenameParameter);
        } else {
            //strcpy(voxelPersistFilename, _wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
            strcpy(_voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
        }

        qDebug("loading voxels from file: %s...\n", _voxelPersistFilename);

        persistantFileRead = _serverTree.readFromSVOFile(_voxelPersistFilename);
        if (persistantFileRead) {
            PerformanceWarning warn(_shouldShowAnimationDebug,
                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", _shouldShowAnimationDebug);
            
            // after done inserting all these voxels, then reaverage colors
            _serverTree.reaverageVoxelColors(_serverTree.rootNode);
            qDebug("Voxels reAveraged\n");
        }
        
        _serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
        qDebug("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
        unsigned long nodeCount         = _serverTree.rootNode->getSubTreeNodeCount();
        unsigned long internalNodeCount = _serverTree.rootNode->getSubTreeInternalNodeCount();
        unsigned long leafNodeCount     = _serverTree.rootNode->getSubTreeLeafNodeCount();
        qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
        
        // now set up VoxelPersistThread
        _voxelPersistThread = new VoxelPersistThread(&_serverTree, _voxelPersistFilename);
        if (_voxelPersistThread) {
            _voxelPersistThread->initialize(true);
        }
    }

    // Check to see if the user passed in a command line option for loading an old style local
    // Voxel File. If so, load it now. This is not the same as a voxel persist file
    const char* INPUT_FILE = "-i";
    const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
    if (voxelsFilename) {
        _serverTree.readFromSVOFile(voxelsFilename);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        _packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND;
        if (_packetsPerClientPerInterval < 1) {
            _packetsPerClientPerInterval = 1;
        }
        qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
    }
    
    // for now, initialize the environments with fixed values
    _environmentData[1].setID(1);
    _environmentData[1].setGravity(1.0f);
    _environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
    _environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
    _environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
    _environmentData[2].setID(2);
    _environmentData[2].setGravity(1.0f);
    _environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
    _environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
    _environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
    _environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue

    sockaddr senderAddress;
    
    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t packetLength;
    
    timeval lastDomainServerCheckIn = {};

    // set up our jurisdiction broadcaster...
    _jurisdictionSender = new JurisdictionSender(_jurisdiction);
    if (_jurisdictionSender) {
        _jurisdictionSender->initialize(true);
    }
    
    // set up our VoxelServerPacketProcessor
    _voxelServerPacketProcessor = new VoxelServerPacketProcessor(this);
    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->initialize(true);
    }
    
    // loop to send to nodes requesting data
    while (true) {
    
        if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            break;
        }
        
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn(_uuid.toRfc4122().constData());
        }
        
        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
            packetVersionMatch(packetData)) {

            int numBytesPacketHeader = numBytesForPacketHeader(packetData);

            if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
                // need to make sure we have it in our nodeList.
                uint16_t nodeID = 0;
                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
                Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
                                                       &senderAddress,
                                                       NODE_TYPE_AGENT,
                                                       nodeID);

                NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
                
                VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData();
                if (nodeData && !nodeData->isVoxelSendThreadInitalized()) {
                    nodeData->initializeVoxelSendThread(this);
                }
                
            } else if (packetData[0] == PACKET_TYPE_PING) {
                // If the packet is a ping, let processNodeData handle it.
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_DOMAIN) {
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
                if (_jurisdictionSender) {
                    _jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
                }
            } else if (_voxelServerPacketProcessor) {
                _voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
            } else {
                qDebug("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
            }
        }
    }
    
    delete _jurisdiction;
    
    if (_jurisdictionSender) {
        _jurisdictionSender->terminate();
        delete _jurisdictionSender;
    }

    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->terminate();
        delete _voxelServerPacketProcessor;
    }

    if (_voxelPersistThread) {
        _voxelPersistThread->terminate();
        delete _voxelPersistThread;
    }
    
    // tell our NodeList we're done with notifications
    nodeList->removeHook(&_nodeWatcher);
    
    pthread_mutex_destroy(&_treeLock);
}
Пример #19
0
bg_shm_t * bg_shm_alloc_write(int size)
  {
  int shm_fd = -1;
  void * addr;
  bg_shm_t * ret = NULL;
  char name[SHM_NAME_MAX];
  int id = 0;
  pthread_mutexattr_t attr;
  int real_size = get_real_size(size);
  
  while(1)
    {
    id++;
    
    gen_name(id, name);
    
    if((shm_fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL,
                          S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
      {
      if(errno != EEXIST)
        {
        bg_log(BG_LOG_ERROR, LOG_DOMAIN,
               "shm_open of %s failed: %s", name, strerror(errno));
        return NULL;
        }
      }
    else
      break;
    }
  
  if(ftruncate(shm_fd, real_size))
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN,
           "ftruncate failed: %s", strerror(errno));
    goto fail;
    }

  if((addr = mmap(0, real_size, PROT_READ | PROT_WRITE,
                  MAP_SHARED, shm_fd, 0)) == MAP_FAILED)
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN,
           "mmap failed: %s", strerror(errno));
    return NULL;
    }

  ret = calloc(1, sizeof(*ret));
  ret->addr = addr;
  ret->size = size;
  ret->id = id;
  ret->wr = 1;
  ret->rc = (refcounter_t*)(ret->addr + align_size(size));

  /* Initialize process shared mutex */

  pthread_mutexattr_init(&attr);
  if(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED))
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN,
           "cannot create process shared mutex: %s", strerror(errno));
    goto fail;
    }
  pthread_mutex_init(&ret->rc->mutex, &attr);

  bg_log(BG_LOG_DEBUG, LOG_DOMAIN,
         "created shm segment (write) %s", name);

  ret->rc->refcount = 0;
  fail:
  
  close(shm_fd);
  
  return ret;
  }
Пример #20
0
/*
 * Initialize the Interprocess Communication system and its
 * associated shared memory structure. It first creates a
 * temporary file using either the mkstemp() function or the
 * tempnam() and open() functions. If the process model is in
 * use,it than sets the file large enough to hold the
 * filebench_shm and an additional Megabyte. The file is then
 * memory mapped. If the process model is not in use, it simply
 * mallocs a region of sizeof (filebench_shm_t).
 *
 * Once the shared memory region / file is created, ipc_init
 * initializes various locks pointers, and variables in the
 * shared memory. It also uses ftok() to get a shared memory
 * semaphore key for later use in allocating shared semaphores.
 */
void
ipc_init(void)
{
	filebench_shm_t *buf = malloc(MB);
	key_t key;
	caddr_t c1;
	caddr_t c2;
	int semid;

#ifdef HAVE_MKSTEMP
	shmpath = (char *)malloc(128);
	(void) strcpy(shmpath, "/var/tmp/fbenchXXXXXX");
	shmfd = mkstemp(shmpath);
#else
	shmfd   = open(shmpath, O_CREAT | O_RDWR | O_TRUNC, 0666);
	shmpath = tempnam("/var/tmp", "fbench");
#endif	/* HAVE_MKSTEMP */

#ifdef USE_PROCESS_MODEL

	if (shmfd  < 0) {
		filebench_log(LOG_FATAL, "Cannot open shm %s: %s",
		    shmpath,
		    strerror(errno));
		exit(1);
	}

	(void) lseek(shmfd, sizeof (filebench_shm_t), SEEK_SET);
	if (write(shmfd, buf, MB) != MB) {
		filebench_log(LOG_FATAL,
		    "Cannot allocate shm: %s", strerror(errno));
		exit(1);
	}

	/* LINTED E_BAD_PTR_CAST_ALIGN */
	if ((filebench_shm = (filebench_shm_t *)mmap((caddr_t)0,
	    sizeof (filebench_shm_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, shmfd, 0)) == NULL) {
		filebench_log(LOG_FATAL, "Cannot mmap shm");
		exit(1);
	}

#else
	if ((filebench_shm =
	    (filebench_shm_t *)malloc(sizeof (filebench_shm_t))) == NULL) {
		filebench_log(LOG_FATAL, "Cannot malloc shm");
		exit(1);
	}
#endif /* USE_PROCESS_MODEL */

	c1 = (caddr_t)filebench_shm;
	c2 = (caddr_t)&filebench_shm->marker;

	(void) memset(filebench_shm, 0, c2 - c1);
	filebench_shm->epoch = gethrtime();
	filebench_shm->debug_level = 2;
	filebench_shm->string_ptr = &filebench_shm->strings[0];
	filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr;
	filebench_shm->path_ptr = &filebench_shm->filesetpaths[0];

	/* Setup mutexes for object lists */
	(void) pthread_mutex_init(&filebench_shm->fileset_lock,
	    ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->procflow_lock,
	    ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->threadflow_lock,
	    ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->flowop_lock, ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->msg_lock, ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->eventgen_lock,
	    ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->malloc_lock, ipc_mutexattr());
	(void) pthread_mutex_init(&filebench_shm->ism_lock, ipc_mutexattr());
	(void) pthread_cond_init(&filebench_shm->eventgen_cv, ipc_condattr());
	(void) pthread_rwlock_init(&filebench_shm->flowop_find_lock,
	    ipc_rwlockattr());
	(void) pthread_rwlock_init(&filebench_shm->run_lock, ipc_rwlockattr());
	(void) pthread_rwlock_rdlock(&filebench_shm->run_lock);

	(void) ipc_mutex_lock(&filebench_shm->ism_lock);

	/* Create semaphore */
	if ((key = ftok(shmpath, 1)) < 0) {
		filebench_log(LOG_ERROR, "cannot create sem: %s",
		    strerror(errno));
		exit(1);
	}

	if ((semid = semget(key, 0, 0)) != -1)
		(void) semctl(semid, 0, IPC_RMID);

	filebench_shm->semkey = key;
	filebench_shm->log_fd = -1;
	filebench_shm->dump_fd = -1;
	filebench_shm->eventgen_hz = 0;
	filebench_shm->shm_id = -1;

	free(buf);
}
Пример #21
0
int32_t dt_camera_capture_job_run(dt_job_t *job)
{
  dt_camera_capture_t *t=(dt_camera_capture_t*)job->param;
  int total;
  char message[512]= {0};
  double fraction=0;

  total = t->total = t->brackets ? t->count * t->brackets : t->count;
  snprintf(message, 512, ngettext ("capturing %d image", "capturing %d images", total), total );

  pthread_mutex_init(&t->mutex, NULL);
  pthread_cond_init(&t->done, NULL);

  // register listener
  dt_camctl_listener_t *listener;
  listener = g_malloc(sizeof(dt_camctl_listener_t));
  memset(listener, 0, sizeof(dt_camctl_listener_t));
  listener->data=t;
  listener->image_downloaded=_camera_capture_image_downloaded;
  listener->request_image_path=_camera_request_image_path;
  listener->request_image_filename=_camera_request_image_filename;
  dt_camctl_register_listener(darktable.camctl, listener);

  /* try to get exp program mode for nikon */
  char *expprogram = (char *)dt_camctl_camera_get_property(darktable.camctl, NULL, "expprogram");

  /* if fail, lets try fetching mode for cannon */
  if(!expprogram)
    expprogram = (char *)dt_camctl_camera_get_property(darktable.camctl, NULL, "autoexposuremode");

  /* Fetch all values for shutterspeed and initialize current value */
  GList *values=NULL;
  gconstpointer original_value=NULL;
  const char *cvalue = dt_camctl_camera_get_property(darktable.camctl, NULL, "shutterspeed");
  const char *value = dt_camctl_camera_property_get_first_choice(darktable.camctl, NULL, "shutterspeed");

  /* get values for bracketing */
  if (t->brackets && expprogram && expprogram[0]=='M' && value && cvalue)
  {
    do
    {
      // Add value to list
      values = g_list_append(values, g_strdup(value));
      // Check if current values is the same as original value, then lets store item ptr
      if (strcmp(value,cvalue) == 0)
        original_value = g_list_last(values)->data;
    }
    while ((value = dt_camctl_camera_property_get_next_choice(darktable.camctl, NULL, "shutterspeed")) != NULL);
  }
  else
  {
    /* if this was an intended bracket capture bail out */
    if(t->brackets)
    {
      dt_control_log(_("please set your camera to manual mode first!"));
      return 1;
    }
  }

  /* create the bgjob plate */
  const guint *jid  = dt_control_backgroundjobs_create(darktable.control, 0, message);

  GList *current_value = g_list_find(values,original_value);
  for(uint32_t i=0; i<t->count; i++)
  {
    // Delay if active
    if(t->delay)
      g_usleep(t->delay*G_USEC_PER_SEC);

    for(uint32_t b=0; b<(t->brackets*2)+1; b++)
    {
      // If bracket capture, lets set change shutterspeed
      if (t->brackets)
      {
        if (b == 0)
        {
          // First bracket, step down time with (steps*brackets), also check so we never set the longest shuttertime which would be bulb mode
          for(uint32_t s=0; s<(t->steps*t->brackets); s++)
            if (g_list_next(current_value) && g_list_next(g_list_next(current_value)))
              current_value = g_list_next(current_value);
        }
        else
        {
          // Step up with (steps)
          for(uint32_t s=0; s<t->steps; s++)
            if(g_list_previous(current_value))
              current_value = g_list_previous(current_value);
        }
      }

      // set the time property for bracket capture
      if (t->brackets && current_value)
        dt_camctl_camera_set_property_string(darktable.camctl, NULL, "shutterspeed", current_value->data);

      // Capture image
      dt_camctl_camera_capture(darktable.camctl,NULL);

      fraction += 1.0/total;
      dt_control_backgroundjobs_progress(darktable.control, jid, fraction);
    }

    // lets reset to original value before continue
    if (t->brackets)
    {
      current_value = g_list_find(values,original_value);
      dt_camctl_camera_set_property_string(darktable.camctl, NULL, "shutterspeed", current_value->data);
    }
  }

  /* wait for last image capture before exiting job */
  pthread_mutex_lock(&t->mutex);
  pthread_cond_wait(&t->done, &t->mutex);
  pthread_mutex_unlock(&t->mutex);
  pthread_mutex_destroy(&t->mutex);
  pthread_cond_destroy(&t->done);

  /* cleanup */
  dt_control_backgroundjobs_destroy(darktable.control, jid);
  dt_import_session_destroy(t->shared.session);
  dt_camctl_unregister_listener(darktable.camctl, listener);
  g_free(listener);

  // free values
  if(values)
  {
    g_list_free_full(values, g_free);
  }

  return 0;
}
Пример #22
0
void sem_init(struct pthread_semaphore * semaphore, int init_count)
{
    semaphore->counter = init_count;
    pthread_cond_init(&semaphore->waiting, NULL);
    pthread_mutex_init(&semaphore->crit, NULL);
}
Пример #23
0
static int retrieve_segment(struct segment * seg)
{
    char proc[256];
    snprintf(proc, 256, "rsg%u", g_nodeId);
    prctl(PR_SET_NAME, proc, 0, 0, 0);
    int rv = -1;
    log_print(g_log, "retrieve_segment: trying to retrieve segment %s[%d - %d].",
              seg->name->full_name, 0, seg->num_chunks-1);

    pthread_mutex_lock(&g_lock);
    int retries = g_interest_attempts;
    int timeout_ms = g_timeout_ms;
    pthread_mutex_unlock(&g_lock);
    int ttl = MAX_TTL;

    if ((seg->opts->mode & CCNFDNB_USE_RETRIES) == CCNFDNB_USE_RETRIES) {
        retries = seg->opts->retries;
    }
    if ((seg->opts->mode & CCNFDNB_USE_TIMEOUT) == CCNFDNB_USE_TIMEOUT) {
        timeout_ms = seg->opts->timeout_ms;
    }
    if ((seg->opts->mode & CCNFDNB_USE_TTL) == CCNFDNB_USE_TTL) {
        ttl = seg->opts->ttl;
    }

    struct chunk chunk_window[MAX_INTEREST_PIPELINE];
    PENTRY _pit_handles[MAX_INTEREST_PIPELINE];
    int pit_to_chunk[PIT_SIZE];
    memset(&pit_to_chunk, 0, sizeof(pit_to_chunk));
    struct bitmap * window = bit_create(MAX_INTEREST_PIPELINE);
    struct bitmap * missing = bit_create(seg->num_chunks);

    char str[MAX_NAME_LENGTH], comp[MAX_NAME_LENGTH];
    strncpy(str, seg->name->full_name, seg->name->len);

    int rtt_est = timeout_ms;
    int cwnd = 1;
    int ssthresh = DEFAULT_INTEREST_PIPELINE;
    int fullfilled = 0;
    int min_rtt_est = 10;

    int current_chunk = 0;
    cc_state state = SLOW_START;
    int tx;

    _segment_q_t seg_q;
    pthread_mutex_init(&seg_q.mutex, NULL);
    pthread_cond_init(&seg_q.cond, NULL);
    seg_q.rcv_window = 0;
    seg_q.max_window = &cwnd;
    seg_q.rcv_chunks = linked_list_init(NULL);
    seg_q.base = seg->name;
    ccnfdnl_reg_segment(&seg_q);

    int i;
    window->num_bits = cwnd;
    while (!bit_allSet(missing)) {
        tx = cwnd;
        window->num_bits = cwnd;

        log_debug(g_log, "state = %d, cwnd = %d, ssthresh = %d rtt_est = %d",
                  state, cwnd, ssthresh, rtt_est);

        while (tx && (current_chunk < seg->num_chunks)) {
            snprintf(comp, MAX_NAME_LENGTH - seg->name->len, "/%d", current_chunk);
            strncpy(str + seg->name->len, comp, seg->name->len);
            i = bit_find(window);
            if (i < 0 || i >= MAX_INTEREST_PIPELINE) {
                /* we must still be waiting for data */
                break;
            }
            chunk_window[i].intr.name = content_name_create(str);
            chunk_window[i].intr.ttl = ttl;
            chunk_window[i].seq_no = current_chunk;
            chunk_window[i].retries = retries;

            _pit_handles[i] = PIT_get_handle(chunk_window[i].intr.name);
            if (!_pit_handles[i]) {
                bit_clear(window, i);
                break;
            }
            pit_to_chunk[_pit_handles[i]->index] = i;
            pthread_mutex_unlock(_pit_handles[i]->mutex);

            struct content_obj * co = CS_get(chunk_window[i].intr.name);
            if (!co) {
                log_debug(g_log, "expressing new interest: %s", chunk_window[i].intr.name->full_name);
                ccnfdnb_fwd_interest(&chunk_window[i].intr);
                tx--;
            } else {
                log_debug(g_log, "retrieved %s from CS", co->name->full_name);

                PENTRY pe = PIT_exact_match(chunk_window[i].intr.name);
                *pe->obj = co;
                pthread_mutex_unlock(pe->mutex);

                pthread_mutex_lock(&seg_q.mutex);

                linked_list_append(seg_q.rcv_chunks, pe);
                seg_q.rcv_window++;

                pthread_mutex_unlock(&seg_q.mutex);
            }

            current_chunk++;
        }
        log_debug(g_log, "tx window full");

        pthread_mutex_lock(&seg_q.mutex);

        if (seg_q.rcv_chunks->len == 0) {
            struct timespec wait;
            ts_fromnow(&wait);
            ts_addms(&wait, 2 * rtt_est);

            rv = pthread_cond_timedwait(&seg_q.cond, &seg_q.mutex, &wait);
            if ((rv == ETIMEDOUT) && !seg_q.rcv_chunks->len) {
                /* we timed out, we need to rtx */
                rtt_est += rtt_est / 2;
                if (rtt_est > PIT_LIFETIME_MS)
                    rtt_est = PIT_LIFETIME_MS / 2;
            }
        } else {
            int pit_ages = 0;
            int pits_fulfilled = 0;
            while (seg_q.rcv_chunks->len > 0) {
                PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0);
                log_assert(g_log, pe != NULL, "invalid pit entry");

                pthread_mutex_lock(pe->mutex);
                log_debug(g_log, "pit entry %s fulfilled", (*pe->obj)->name->full_name);

                int chunk_id = pit_to_chunk[pe->index];
                log_assert(g_log, chunk_id >= 0, "invalid chunk id");

                if (chunk_window[chunk_id].seq_no == 0) {
                    seg->obj->publisher = (*pe->obj)->publisher;
                    seg->obj->timestamp = (*pe->obj)->timestamp;
                    seg->chunk_size = (*pe->obj)->size;
                }
                int offset = chunk_window[chunk_id].seq_no * seg->chunk_size;
                memcpy(&seg->obj->data[offset], (*pe->obj)->data, (*pe->obj)->size);
                content_obj_destroy(*pe->obj);

                struct timespec now;
                ts_fromnow(&now);
                ts_addms(&now, PIT_LIFETIME_MS);
                pit_ages += PIT_age(pe);
				pits_fulfilled++;

                pit_to_chunk[pe->index] = -1;
                PIT_release(pe);
                free(_pit_handles[chunk_id]);
                _pit_handles[chunk_id] = NULL;
                bit_clear(window, chunk_id);
                bit_set(missing, chunk_window[chunk_id].seq_no);
                log_debug(g_log, "retrieved chunk %s", chunk_window[chunk_id].intr.name->full_name);
                content_name_delete(chunk_window[chunk_id].intr.name);
                chunk_window[chunk_id].intr.name = NULL;
                cwnd++;
                if (state == CONG_AVOID)
                    fullfilled++;
            }

            rtt_est -= floor(pit_ages / pits_fulfilled);
            if (rtt_est < min_rtt_est)
                rtt_est = min_rtt_est;
        }

        pthread_mutex_unlock(&seg_q.mutex);

        for (i = 0; i < MAX_INTEREST_PIPELINE; i++) {
            if (bit_test(window, i)) {
                if (!_pit_handles[i]) {
                    continue;
                }
                pthread_mutex_lock(_pit_handles[i]->mutex);
                if (PIT_age(_pit_handles[i]) > (2 * rtt_est)) {
                    PIT_refresh(_pit_handles[i]);
                    chunk_window[i].retries--;
                    ccnfdnb_fwd_interest(&chunk_window[i].intr);
                    log_debug(g_log, "rtx interest: %s (rtt = %d)",
                              chunk_window[i].intr.name->full_name, rtt_est);
                    ssthresh = cwnd / 2 + 1;
                    cwnd = 1;
                    state = SLOW_START;
                }
                pthread_mutex_unlock(_pit_handles[i]->mutex);
            }
        }

        if ((cwnd >= ssthresh) && (state == SLOW_START))
            state = CONG_AVOID;
        if (state == SLOW_START)
            fullfilled = 0;
        if ((fullfilled == cwnd) && (state == CONG_AVOID)) {
            cwnd++;
            fullfilled = 0;
        }
        if (cwnd > MAX_INTEREST_PIPELINE)
            cwnd = MAX_INTEREST_PIPELINE;

        /*log_debug(g_log, "cwnd = %d, ssthresh = %d", cwnd, ssthresh);*/
    }

    log_debug(g_log, "retrieve_segment: finished for %s[%d-%d]",
              seg->name->full_name, 0, seg->num_chunks-1);

    rv = 0;

    PIT_print();
    ccnfdnl_unreg_segment(&seg_q);
    pthread_mutex_destroy(&seg_q.mutex);
    pthread_cond_destroy(&seg_q.cond);
    while (seg_q.rcv_chunks->len) {
        PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0);
        content_obj_destroy(*pe->obj);
        PIT_release(pe);
    }

    bit_destroy(window);
    bit_destroy(missing);

    return rv;
}
Пример #24
0
mlt_slices mlt_slices_init( int threads, int policy, int priority )
{
	pthread_attr_t tattr;
	struct sched_param param;
	mlt_slices ctx = (mlt_slices)calloc( 1, sizeof( struct mlt_slices_s ) );
	char *env = getenv( ENV_SLICES );
#ifdef _WIN32
	int cpus = GetCurrentProcessorNumber( );
#else
	int cpus = sysconf( _SC_NPROCESSORS_ONLN );
#endif
	int i, env_val = env ? atoi(env) : 0;

	/* check given threads count */
	if ( !env || !env_val )
	{
		if ( threads < 0 )
			threads = -threads * cpus;
		else if ( !threads )
			threads = cpus;
	}
	else if ( env_val < 0 )
	{
		if ( threads < 0 )
			threads = env_val * threads * cpus;
		else if ( !threads )
			threads = -env_val * cpus;
		else
			threads = -env_val * threads;
	}
	else // env_val > 0
	{
		if ( threads < 0 )
			threads = env_val * threads;
		else if ( !threads )
			threads = env_val;
		else
			threads = threads;
	}
	if ( threads > MAX_SLICES )
		threads = MAX_SLICES;

	ctx->count = threads;

	/* init attributes */
	pthread_mutex_init ( &ctx->cond_mutex, NULL );
	pthread_cond_init ( &ctx->cond_var_job, NULL );
	pthread_cond_init ( &ctx->cond_var_ready, NULL );
	pthread_attr_init( &tattr );
	pthread_attr_setschedpolicy( &tattr, policy );
	param.sched_priority = priority;
	pthread_attr_setschedparam( &tattr, &param );

	/* run worker threads */
	for ( i = 0; i < ctx->count; i++ )
	{
		pthread_create( &ctx->threads[i], &tattr, mlt_slices_worker, ctx );
		pthread_setschedparam( ctx->threads[i], policy, &param);
	}

	pthread_attr_destroy( &tattr );

	/* ready wait workers */
	pthread_mutex_lock( &ctx->cond_mutex );
	while ( ctx->readys != ctx->count )
		pthread_cond_wait( &ctx->cond_var_ready, &ctx->cond_mutex );
	pthread_mutex_unlock( &ctx->cond_mutex );

	/* return context */
	return ctx;
}
Пример #25
0
int main( int argc , char *argv[]) {
	signal(SIGINT, ctrlHandler);


	n_linhas = linhas("localdns.txt");

	#ifdef DEBUG
	printf("Verificacao dos ficheiros presentes.\n");
	#endif

	if(verifica_ficheiros("localdns.txt") == 0) {
		printf("Ficheiro localdns.txt inexistente!\n");
		exit(1);
	}
	if(verifica_ficheiros("config.txt") == 0) {
		printf("Ficheiro config.txt inexistente!\n");
		exit(1);
	}

	#ifdef DEBUG
	printf("Inicializacoes.\n");
	#endif
	unsigned char buf[65536], *reader, *reader2, qname;
	int sockfd, stop;
	struct DNS_HEADER *dns = NULL;
	struct stats stat;

	struct sockaddr_in servaddr, dest;
	socklen_t len;

	int i, np, r;

	cfg_process = 1;
	stats_process = 1;

	pthread_mutex_init(&mutex, NULL);
	pthread_cond_init(&cond, NULL);

	#ifdef DEBUG
	printf("Criacao das Filas Normal e Prioridade e da lista de Domains locais.\n");
	#endif
	Fila fila_normal = cria_fila();
	Fila fila_prioridade = cria_fila();

	Local l_domains = cria_lista();

	// Hora de arranque do Servidor
	time_t clk = time(NULL);
	strcpy(stat.data_hora_arranque, ctime(&clk));

	// Inicializaco Memoria Partilhada
	init_shm();
	
	ptr_config->flag = 0;

	printf("[PAI - MAIN] PID Main = %d PID DO MEU PAI = %d\n", getpid(), getppid());

	char* data;

	#ifdef DEBUG
	printf("Criacao processo de configuracoes.\n");
	#endif
	if ((cfg_process = fork()) == 0) {
		signal(SIGUSR1, handler_CFG);
		#ifdef DEBUG
		printf("RELEASE CFG.\n");
		printf("Mapeamento de localdns.txt.\n");
		#endif
		mapear("localdns.txt");
		#ifdef DEBUG
		printf("Leitura de config.txt para estrutura em memoria partilhada.\n");
		#endif
		file2memory("config.txt");
		if(signal(SIGALRM, SIG_IGN) == SIG_ERR) {
			perror("SIGALRM Ignore error");
			exit(1);
		}
	} else {
		usleep(200000);

		if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
			perror("Signal ignore error");
			exit(1);
		}

		#ifdef DEBUG
		printf("RELEASE MAIN.\n");
		#endif

		#ifdef DEBUG
		printf("Extrair enderecos e ip's locais do mmap\n");
		#endif
		token_mmap(l_domains, ptr_config->data);

		// Check arguments
		if(argc <= 1) {
			printf("Usage: %s <port>\n", argv[0]);
			exit(1);
		}
		
		// Get server UDP port number
		int port = atoi(argv[1]);
		
		if(port <= 0) {
			printf("Usage: %s <port>\n", argv[0]);
			exit(1);
		}

		// ****************************************
		// Create socket & bind
		// ****************************************
		// Create UDP socket
	    sockfd = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
		if (sockfd < 0) {
   	      printf("ERROR opening socket.\n");
			 exit(1);
		}

		// Prepare UDP to bind port
		bzero(&servaddr,sizeof(servaddr));
		servaddr.sin_family = AF_INET;
		servaddr.sin_addr.s_addr=htonl(INADDR_ANY); 
		servaddr.sin_port=htons(port);
		
		// ****************************************
		// Receive questions
		// ****************************************

		// Bind application to UDP port
		int res = bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
		
		if(res < 0) {
	         printf("Error binding to port %d.\n", servaddr.sin_port);
			 
			 if(servaddr.sin_port <= 1024) {
				 printf("To use ports below 1024 you may need additional permitions. Try to use a port higher than 1024.\n");
			 } else {
				 printf("Please make sure this UDP port is not being used.\n");
			 }
			 exit(1);
		}


		#ifdef DEBUG
		printf("Criacao named pipe para as estatisticas\n.");
		#endif
		char* n_pipe = ptr_config->Named_pipe;
		if(verifica_ficheiros(n_pipe) == 1) {
			printf("Named pipe ja existente! A eliminar...\n");
			unlink(n_pipe);
		}
		if(((np = mkfifo(n_pipe, O_CREAT|O_EXCL|0600)<0)) && (errno != EEXIST)) {
			perror("mkfifo");
			exit(1);
		} 
		if (np != 0) {
			fprintf(stderr, "Impossivel criar fifo %s\n", n_pipe);
			return 1;
		}
		if((np = open(n_pipe, O_RDWR)) < 0) {
			perror("Opening Named Pipe");
			exit(1);
		}
	}

	#ifdef DEBUG
	printf("A sair = %d\n", getpid());
	#endif

	#ifdef DEBUG
	printf("Criacao Processo de estatisticas\n");
	#endif
	if(cfg_process != 0) {
		stats_process = fork();
		if(stats_process == 0) {
			if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
				perror("Signal ignore error");
				exit(1);
			}
			#ifdef DEBUG
			printf("RELEASE STATS.\n");
			#endif
		} else {
			usleep(200000);
			if(signal(SIGALRM, SIG_IGN) == SIG_ERR) {
				perror("SIGALRM Ignore error");
				exit(1);
			}
		}
	}

	#ifdef DEBUG 
	printf("Quem chega primeiro = %d\n", getpid()); 
	#endif

	if(cfg_process != 0 && stats_process != 0) {
		#ifdef DEBUG
		printf("A preencher struct para argumento da funcao do thread.\n");
		#endif
		struct thread_data t_data;
		t_data.normal = fila_normal;
		t_data.prioridade = fila_prioridade;
		t_data.domains = l_domains;

		int N_THREADS = ptr_config->N_threads;

		p_threads = malloc(sizeof(*p_threads) * N_THREADS);

		#ifdef DEBUG
		printf("A criar a pool de threads.\n");
		#endif

		for(i=0;i < N_THREADS;i++) {
			pthread_create(p_threads+i, NULL, requester, (void*)&t_data);
		}
		usleep(50000);

		printf("\n\n-- Waiting for DNS message --\n\n");
	}

	while(1) {
		if((cfg_process == 0) && (ptr_config->saida == 1)) {	// MODO MANUNTENCAO
			file2memory("config.txt");
			ptr_config->saida = 0;
			usleep(100000);
			printf("\n-- Waiting for DNS message --\n");
		}
		if(cfg_process != 0 && stats_process != 0) {		// GESTOR PEDIDOS
			usleep(200000);
			
			len = sizeof(dest);

			// Thread blocking!
			if(recvfrom (sockfd, (unsigned char*)buf, 65536 , 0 , (struct sockaddr*)&dest , &len) < 0) {
				perror("Error in recvfrom");
				exit(1);
			}

			printf("DNS message received\n");

			// Process received message
			dns = (struct DNS_HEADER*) buf;
			qname = (unsigned char)buf[sizeof(struct DNS_HEADER)];
			reader = &buf[sizeof(struct DNS_HEADER)];

			// We only need to process the questions
			// We only process DNS messages with one question
			// Get the query fields according to the RFC specification
			struct QUERY query;
			if(ntohs(dns->q_count) == 1) {
				// Get NAME
				query.name = convertRFC2Name(reader,buf,&stop);
				reader = reader + stop;
				
				// Get QUESTION structure
				query.ques = (struct QUESTION*)(reader);
				reader = reader + sizeof(struct QUESTION);
				
				// Check question type. We only need to process A records.
				if(ntohs(query.ques->qtype) == 1) {
					printf("A record request.\n\n");
				} else {
					printf("NOT A record request!! Ignoring DNS message!\n");
					continue;
				}	
			} else {
				printf("\n\nDNS message must contain one question!! Ignoring DNS message!\n\n");
				continue;
			}

			#ifdef DEBUG
			printf("ID PEDIDO = %d\n", dns->id);
			#endif


			/***** VALIDAR PEDIDO *****/
			valido = 0;

			// 1. Verificar se e' localDomain (Se for, vai para a lista prioritaria)
			// TRABALHO DOS THREADS...
			if(strstr(query.name, ptr_config->localDomain) != NULL) {
				valido = 1;
				stat.pedidos_local += 1;
				insere_pedido(fila_prioridade, receber_info(query.name, &dest, dns->id, sockfd));
			} else if(ptr_config->flag % 2 == 0) {	// 2. Verificar se é um dos dominios autorizados (ptr_config->domains[])
				for(i=0; i < ptr_config->n_domains; i++) {
					if(strstr(query.name, ptr_config->domains[i]) != NULL) {
						valido = 1;
						stat.pedidos_externos += 1;
						insere_pedido(fila_normal, receber_info(query.name, &dest, dns->id, sockfd));
						break;
					}
				}
			}

			#ifdef DEBUG
			imprimir_fila(fila_normal);
			imprimir_fila(fila_prioridade);
			#endif

			if(valido == 1) {
				#ifdef DEBUG
				printf("A ENVIAR SINAL PARA A THREAD...\n");
				#endif
				pthread_cond_signal(&cond);		
			} else {	
				if(ptr_config->flag % 2 != 0) {
					printf("Durante o modo de manuntencao apenas pedidos locais sao aceites!\n");
					printf("A enviar 0.0.0.0...\n");	
				} else {
					printf("Pedido negado!\nDe momento os dominios aceites sao:\n");
					for(i=0;i<ptr_config->n_domains;i++) {
						printf("-> Dominio %d = %s\n",i,ptr_config->domains[i]);
					}
				}
				sendReply(dns->id, query.name, inet_addr("0.0.0.0"), sockfd, dest);
				printf("\n\n-- Waiting for DNS message --\n\n");
			}

			if(valido == 0) {
				stat.pedidos_negados += 1;
			}
			stat.total_pedidos += 1;

			// Enviar dados das ESTATISTICAS para o named pipe aqui
			#ifdef DEBUG
			printf("A escrever estatisticas para o named pipe\n.");
			#endif
			write(np, &stat, sizeof(struct stats));
		}
		if (stats_process == 0 && cfg_process != 0) {	// STATS Process
			signal(SIGALRM, handler_alarm);

			Config* ptr;
			if ((ptr = shmat(shmID, NULL, 0)) == (Config *) -1) {
				perror("error in shmat");
				exit(1);
			}

			struct stats st;
			char* n_pipe = ptr_config->Named_pipe;

			if((r = open(n_pipe, O_RDONLY)) < 0) {
				perror("Child open Named pipe");
				exit(1);
			}

			read(r, &st, sizeof(struct stats));
			linha(st.data_hora_arranque);

			time_t clk2 = time(NULL);
			strcpy(st.data_info, ctime(&clk2));
			linha(st.data_info);

			t_p = st.total_pedidos;
			p_n = st.pedidos_negados;
			p_l = st.pedidos_local;
			p_e = st.pedidos_externos;
			strcpy(d_a, st.data_hora_arranque);
			strcpy(u_i, st.data_info);

			alarm(FREQ);
		}
	}

	return 0;
}
Пример #26
0
int
main(int argc, char **argv)
{
  if (argc <= 1) {
    usage(argv[0]);
    exit(-1);
  }

  char ch;
  while ((ch = getopt(argc, argv, "t:b:d:s:l:w:o:rh")) != -1) {
    switch (ch) {
//    case 't': num_threads = atoi(optarg); break;
    case 't': num_threads = 1; break;
    //case 'b': num_mget    = atoi(optarg); break;
    case 'd': duration    = atof(optarg); break;
    case 's': serverip    = optarg; break;
    case 'l': inputfile   = optarg; break;
    case 'o': outputfolder   = optarg; break;
    case 'w': workingset  = optarg; break;
    case 'r': isreverse   = true; break;
    case 'h': usage(argv[0]); exit(0); break;
    default:
      usage(argv[0]);
      exit(-1);
    }
  }

  if (serverip == NULL || inputfile == NULL || workingset == NULL) {
    usage(argv[0]);
    exit(-1);
  }

  request *requests = requests_init(inputfile);

  pthread_t threads[num_threads];
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);;

  pthread_mutex_init(&printmutex, NULL);

  size_t t;
  thread_param tp[num_threads];
  for (t = 0; t < num_threads; t++) {
    tp[t].requests = requests + t * (num_requests / num_threads);
    tp[t].tid     = t;
    tp[t].num_ops = num_requests / num_threads;
    tp[t].num_puts = tp[t].num_gets = tp[t].num_miss = tp[t].num_hits = 0;
    tp[t].time = tp[t].tput = 0.0;
    int rc = pthread_create(&threads[t], &attr, requests_exec, (void *) &tp[t]);
    if (rc) {
      perror("failed: pthread_create\n");
      exit(-1);
    }
  }

  result_t result;
  result.total_time = 0.0;;
  result.total_tput = 0.0;
  result.total_hits = 0;
  result.total_miss = 0;
  result.total_gets = 0;
  result.total_puts = 0;
  result.num_threads = num_threads;

  for (t = 0; t < num_threads; t++) {
    void *status;
    int rc = pthread_join(threads[t], &status);
    if (rc) {
      perror("error, pthread_join\n");
      exit(-1);
    }
    result.total_time = (result.total_time > tp[t].time) ? result.total_time : tp[t].time;
    result.total_tput += tp[t].tput;
    result.total_hits += tp[t].num_hits;
    result.total_miss += tp[t].num_miss;
    result.total_gets += tp[t].num_gets;
    result.total_puts += tp[t].num_puts;
  }

  printf("total_time = %.2f\n", result.total_time);
  printf("total_tput = %.2f\n", result.total_tput);
  printf("total_hitratio = %.4f\n", (float) result.total_hits / result.total_gets);

  pthread_attr_destroy(&attr);
  printf("bye\n");
  return 0;
}
Пример #27
0
 /**
  * Default Constructor
  **/
 mutex_t() {
   pthread_mutex_init(&m_mutex, NULL);
 }
Пример #28
0
int psmx2_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr,
			struct fid_cntr **cntr, void *context)
{
	struct psmx2_fid_domain *domain_priv;
	struct psmx2_fid_cntr *cntr_priv;
	struct psmx2_fid_wait *wait = NULL;
	struct fi_wait_attr wait_attr;
	int wait_is_local = 0;
	int events;
	uint64_t flags;
	int err;

	events = FI_CNTR_EVENTS_COMP;
	flags = 0;
	domain_priv = container_of(domain, struct psmx2_fid_domain, domain);

	switch (attr->events) {
	case FI_CNTR_EVENTS_COMP:
		events = attr->events;
		break;

	default:
		FI_INFO(&psmx2_prov, FI_LOG_CQ,
			"attr->events=%d, supported=%d\n",
			attr->events, FI_CNTR_EVENTS_COMP);
		return -FI_EINVAL;
	}

	switch (attr->wait_obj) {
	case FI_WAIT_NONE:
	case FI_WAIT_UNSPEC:
		break;

	case FI_WAIT_SET:
		if (!attr->wait_set) {
			FI_INFO(&psmx2_prov, FI_LOG_CQ,
				"FI_WAIT_SET is specified but attr->wait_set is NULL\n");
			return -FI_EINVAL;
		}
		wait = (struct psmx2_fid_wait *)attr->wait_set;
		break;

	case FI_WAIT_FD:
	case FI_WAIT_MUTEX_COND:
		wait_attr.wait_obj = attr->wait_obj;
		wait_attr.flags = 0;
		err = psmx2_wait_open(&domain_priv->fabric->fabric,
				      &wait_attr, (struct fid_wait **)&wait);
		if (err)
			return err;
		wait_is_local = 1;
		break;

	default:
		FI_INFO(&psmx2_prov, FI_LOG_CQ,
			"attr->wait_obj=%d, supported=%d...%d\n",
			attr->wait_obj, FI_WAIT_NONE, FI_WAIT_MUTEX_COND);
		return -FI_EINVAL;
	}

	cntr_priv = (struct psmx2_fid_cntr *) calloc(1, sizeof *cntr_priv);
	if (!cntr_priv) {
		err = -FI_ENOMEM;
		goto fail;
	}

	psmx2_domain_acquire(domain_priv);

	cntr_priv->domain = domain_priv;
	cntr_priv->events = events;
	cntr_priv->wait = wait;
	cntr_priv->wait_is_local = wait_is_local;
	cntr_priv->flags = flags;
	cntr_priv->cntr.fid.fclass = FI_CLASS_CNTR;
	cntr_priv->cntr.fid.context = context;
	cntr_priv->cntr.fid.ops = &psmx2_fi_ops;
	cntr_priv->cntr.ops = &psmx2_cntr_ops;

	pthread_mutex_init(&cntr_priv->trigger_lock, NULL);

	*cntr = &cntr_priv->cntr;
	return 0;
fail:
	if (wait && wait_is_local)
		fi_close(&wait->wait.fid);
	return err;
}
Пример #29
0
/* ************************************** 
 * initialize the list
 * ************************************** */
void list_init(list_t *list) {
    list->head = NULL;
		pthread_mutex_init(&list->lock,NULL);
}
Пример #30
0
int coreaudio_player_alloc(struct auplay_st **stp, struct auplay *ap,
			   struct auplay_prm *prm, const char *device,
			   auplay_write_h *wh, void *arg)
{
	AudioStreamBasicDescription fmt;
	struct auplay_st *st;
	uint32_t sampc, bytc, i;
	OSStatus status;
	int err;

	(void)device;

	st = mem_zalloc(sizeof(*st), auplay_destructor);
	if (!st)
		return ENOMEM;

	st->ap  = mem_ref(ap);
	st->wh  = wh;
	st->arg = arg;

	err = pthread_mutex_init(&st->mutex, NULL);
	if (err)
		goto out;

	err = audio_session_enable();
	if (err)
		goto out;

	fmt.mSampleRate       = (Float64)prm->srate;
	fmt.mFormatID         = audio_fmt(prm->fmt);
	fmt.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger |
		                kAudioFormatFlagIsPacked;
#ifdef __BIG_ENDIAN__
	fmt.mFormatFlags     |= kAudioFormatFlagIsBigEndian;
#endif
	fmt.mFramesPerPacket  = 1;
	fmt.mBytesPerFrame    = prm->ch * bytesps(prm->fmt);
	fmt.mBytesPerPacket   = prm->ch * bytesps(prm->fmt);
	fmt.mChannelsPerFrame = prm->ch;
	fmt.mBitsPerChannel   = 8*bytesps(prm->fmt);

	status = AudioQueueNewOutput(&fmt, play_handler, st, NULL,
				     kCFRunLoopCommonModes, 0, &st->queue);
	if (status) {
		warning("coreaudio: AudioQueueNewOutput error: %i\n", status);
		err = ENODEV;
		goto out;
	}

	sampc = prm->srate * prm->ch * prm->ptime / 1000;
	bytc  = sampc * bytesps(prm->fmt);

	for (i=0; i<ARRAY_SIZE(st->buf); i++)  {

		status = AudioQueueAllocateBuffer(st->queue, bytc,
						  &st->buf[i]);
		if (status)  {
			err = ENOMEM;
			goto out;
		}

		st->buf[i]->mAudioDataByteSize = bytc;

		memset(st->buf[i]->mAudioData, 0,
		       st->buf[i]->mAudioDataByteSize);

		(void)AudioQueueEnqueueBuffer(st->queue, st->buf[i], 0, NULL);
	}

	status = AudioQueueStart(st->queue, NULL);
	if (status)  {
		warning("coreaudio: AudioQueueStart error %i\n", status);
		err = ENODEV;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}