Пример #1
0
static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer,
                             size_t len)
{
  FAR struct inode          *inode;
  FAR struct max11802_dev_s *priv;
  FAR struct touch_sample_s *report;
  struct max11802_sample_s   sample;
  int                        ret;

  iinfo("buffer:%p len:%d\n", buffer, len);
  DEBUGASSERT(filep);
  inode = filep->f_inode;

  DEBUGASSERT(inode && inode->i_private);
  priv  = (FAR struct max11802_dev_s *)inode->i_private;

  /* Verify that the caller has provided a buffer large enough to receive
   * the touch data.
   */

  if (len < SIZEOF_TOUCH_SAMPLE_S(1))
    {
      /* We could provide logic to break up a touch report into segments and
       * handle smaller reads... but why?
       */

      ierr("ERROR: Unsupported read size: %d\n", len);
      return -ENOSYS;
    }

  /* Get exclusive access to the driver data structure */

  ret = sem_wait(&priv->devsem);
  if (ret < 0)
    {
      /* This should only happen if the wait was cancelled by an signal */

      ierr("ERROR: sem_wait: %d\n", errno);
      DEBUGASSERT(errno == EINTR);
      return -EINTR;
    }

  /* Try to read sample data. */

  ret = max11802_sample(priv, &sample);
  if (ret < 0)
    {
      /* Sample data is not available now.  We would ave to wait to get
       * receive sample data.  If the user has specified the O_NONBLOCK
       * option, then just return an error.
       */

      iinfo("Sample data is not available\n");
      if (filep->f_oflags & O_NONBLOCK)
        {
          ret = -EAGAIN;
          goto errout;
       }

      /* Wait for sample data */

      ret = max11802_waitsample(priv, &sample);
      if (ret < 0)
        {
          /* We might have been awakened by a signal */

          ierr("ERROR: max11802_waitsample: %d\n", ret);
          goto errout;
        }
    }

  /* In any event, we now have sampled MAX11802 data that we can report
   * to the caller.
   */

  report = (FAR struct touch_sample_s *)buffer;
  memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
  report->npoints            = 1;
  report->point[0].id        = sample.id;
  report->point[0].x         = sample.x;
  report->point[0].y         = sample.y;

  /* Report the appropriate flags */

  if (sample.contact == CONTACT_UP)
    {
      /* Pen is now up.  Is the positional data valid?  This is important to
       * know because the release will be sent to the window based on its
       * last positional data.
       */

      if (sample.valid)
        {
          report->point[0].flags  = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID;
        }
      else
        {
          report->point[0].flags  = TOUCH_UP | TOUCH_ID_VALID;
        }
    }
  else if (sample.contact == CONTACT_DOWN)
    {
      /* First contact */

      report->point[0].flags  = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
    }
  else /* if (sample->contact == CONTACT_MOVE) */
    {
      /* Movement of the same contact */

      report->point[0].flags  = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
    }

  iinfo("  id:      %d\n", report->point[0].id);
  iinfo("  flags:   %02x\n", report->point[0].flags);
  iinfo("  x:       %d\n", report->point[0].x);
  iinfo("  y:       %d\n", report->point[0].y);

  ret = SIZEOF_TOUCH_SAMPLE_S(1);

errout:
  sem_post(&priv->devsem);
  iinfo("Returning: %d\n", ret);
  return ret;
}
Пример #2
0
ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
{
  FAR struct nxffs_volume_s *volume;
  FAR struct nxffs_wrfile_s *wrfile;
  ssize_t remaining;
  ssize_t nwritten;
  ssize_t total;
  int ret;

  fvdbg("Write %d bytes to offset %d\n", buflen, filep->f_pos);

  /* Sanity checks */

  DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);

  /* Recover the open file state from the struct file instance */

  wrfile = (FAR struct nxffs_wrfile_s *)filep->f_priv;

  /* Recover the volume state from the open file */

  volume = (FAR struct nxffs_volume_s *)filep->f_inode->i_private;
  DEBUGASSERT(volume != NULL);

  /* Get exclusive access to the volume.  Note that the volume exclsem
   * protects the open file list.
   */

  ret = sem_wait(&volume->exclsem);
  if (ret != OK)
    {
      ret = -get_errno();
      fdbg("ERROR: sem_wait failed: %d\n", ret);
      goto errout;
    }

  /* Check if the file was opened with write access */

  if ((wrfile->ofile.oflags & O_WROK) == 0)
    {
      fdbg("ERROR: File not open for write access\n");
      ret = -EACCES;
      goto errout_with_semaphore;
    }

  /* Loop until we successfully appended all of the data to the file (or an
   * error occurs)
   */

  for (total = 0; total < buflen; )
    {
      remaining = buflen - total;

      /* Have we already allocated the data block? */

      if (wrfile->doffset == 0)
        {
          /* No, allocate the data block now, re-packing if necessary. */

          wrfile->datlen = 0;
          ret = nxffs_wralloc(volume, wrfile, remaining);
          if (ret < 0)
            {
              fdbg("ERROR: Failed to allocate a data block: %d\n", -ret);
              goto errout_with_semaphore;
            }
        }

      /* Seek to the FLASH block containing the data block */

      nxffs_ioseek(volume, wrfile->doffset);

      /* Verify that the FLASH data that was previously written is still intact */

      ret = nxffs_reverify(volume, wrfile);
      if (ret < 0)
        {
          fdbg("ERROR: Failed to verify FLASH data block: %d\n", -ret);
          goto errout_with_semaphore;
        }

      /* Append the data to the end of the data block and write the updated
       * block to flash.
       */

      nwritten = nxffs_wrappend(volume, wrfile, &buffer[total], remaining);
      if (nwritten < 0)
        {
          fdbg("ERROR: Failed to append to FLASH to a data block: %d\n", -ret);
          goto errout_with_semaphore;
        }

      /* Decrement the number of bytes remaining to be written */

      total += nwritten;
    }

  /* Success.. return the number of bytes written */

  ret           = total;
  filep->f_pos  = wrfile->datlen;

errout_with_semaphore:
  sem_post(&volume->exclsem);
errout:
  return ret;
}
Пример #3
0
 /*
 This is a simulation of the process diagram
 on slide 38 module 06-Concurrency
 */
 void * p( void * arg )
 {
   unsigned k , mynum ;
   mynum = ( unsigned ) arg ;

   pthread_detach( pthread_self() );

   switch( mynum )
   {
     case 1:
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( & s[1] /* or simply s+1 */ );
	 sem_post( s+1 );
	 sem_post( s+1 );
	 break ;

     case 2:
	 sem_wait( s+1 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+2 );
	 sem_post( s+2 );
	 break ;

     case 3:
	 sem_wait( s+2 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+3 );
	 break ;

     case 4:
	 sem_wait( s+2 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+4 );
	 break ;

     case 5:
	 sem_wait( s+1 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+5 );
	 break ;

     case 6:
	 sem_wait( s+4 ) ;
	 sem_wait( s+5 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+6 );
	 break ;

     case 7:
	 sem_wait( s+1 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+7 );
	 break ;

     case 8:
	 sem_wait( s+3 ) ;
	 sem_wait( s+6 ) ;
	 sem_wait( s+7 ) ;
	 printf("Thread %d started\n", mynum);
	 SPIN ;
	 printf("Thread %d ended\n", mynum);
	 sem_post( s+8 );
	 break ;
   };

   pthread_exit( NULL ) ;
 }
Пример #4
0
DttSP_EXP void
Audio_Callback2 (float **input, float **output, unsigned int nframes)
{
	unsigned int thread;
	BOOLEAN b = reset_em;
	BOOLEAN return_empty=FALSE;
	unsigned int i;
	for(thread=0;thread<threadno;thread++)
	{
		if (top[thread].susp) return_empty = TRUE;
	}

	if (return_empty)
	{
		for(thread=0;thread<threadno;thread++) 
		{
			memset (output[2*thread], 0, nframes * sizeof (float));
			memset (output[2*thread+1], 0, nframes * sizeof (float));
		}
		return;
	}

	if (b)
	{
		//fprintf(stderr, "reset_em!\n"); fflush(stderr);
		//fprintf(stdout,"Audio_Callback2: reset_em = TRUE\n"), fflush(stdout);
		reset_system_audio(nframes);
		for(thread=0;thread<threadno;thread++) {
			memset (output[2*thread], 0, nframes * sizeof (float));
			memset (output[2*thread+1], 0, nframes * sizeof (float));
		}
		return;
    }
#if 0
	if (diversity.flag) {
		// Deal with the transmitter first
		if ((ringb_float_read_space (top[1].jack.ring.o.l) >= nframes)
			&& (ringb_float_read_space (top[1].jack.ring.o.r) >= nframes))
		{
			ringb_float_read (top[1].jack.ring.o.l, output[2], nframes);
			ringb_float_read (top[1].jack.ring.o.r, output[3], nframes);
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}

		// input: copy from port to ring
		if ((ringb_float_write_space (top[1].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[1].jack.ring.i.r) >= nframes))
		{
			ringb_float_write (top[1].jack.ring.i.l, input[2], nframes);
			ringb_float_write (top[1].jack.ring.i.r, input[3], nframes);
		}
		else
		{	
			// rb pathology
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}
		
		// if enough accumulated in ring, fire dsp
		if ((ringb_float_read_space (top[1].jack.ring.i.l) >= top[1].hold.size.frames) &&
			(ringb_float_read_space (top[1].jack.ring.i.r) >= top[1].hold.size.frames))
			sem_post (&top[1].sync.buf.sem);

		//		
		// Deal with the diversity channel next
		//
		if ((ringb_float_read_space (top[0].jack.ring.o.l) >= nframes)
			&& (ringb_float_read_space (top[0].jack.ring.o.r) >= nframes))
		{
			/*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes);
			ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/
			ringb_float_read (top[0].jack.ring.o.l, output[2], nframes);
			ringb_float_read (top[0].jack.ring.o.r, output[3], nframes);
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}

		// Deal with the diversity/phased array channel next

		// input: copy from port to ring
		if ((ringb_float_write_space (top[0].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[0].jack.ring.i.r) >= nframes) &&
			(ringb_float_write_space (top[2].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes))
		{
			REAL *l0 = input[0];
			REAL *r0 = input[1];
			REAL *l2 = input[4];
			REAL *r2 = input[5];
			for (i=0;i<nframes;i++) {
				COMPLEX A = Cmplx(l0[i],r0[i]);
				COMPLEX B = Cmplx(l2[i],r2[i]);
				A = Cscl(Cadd(A,Cmul(B,diversity.scalar)),diversity.gain);
				ringb_float_write (top[0].jack.ring.i.l, &A.re, 1);
				ringb_float_write (top[0].jack.ring.i.r, &A.im, 1);
			}
			/*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes);
			ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}
		
		// if enough accumulated in ring, fire dsp
		if ((ringb_float_read_space (top[0].jack.ring.i.l) >= top[0].hold.size.frames) &&
			(ringb_float_read_space (top[0].jack.ring.i.r) >= top[0].hold.size.frames))
			sem_post (&top[0].sync.buf.sem);


		//
		//  Deal with 2nd receiver channel now
		//

		if ((ringb_float_read_space (top[2].jack.ring.o.l) >= nframes)
			&& (ringb_float_read_space (top[2].jack.ring.o.r) >= nframes))
		{
			/*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes);
			ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/
			ringb_float_read (top[2].jack.ring.o.l, output[4], nframes);
			ringb_float_read (top[2].jack.ring.o.r, output[5], nframes);
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}

		// input: copy from port to ring
		if ((ringb_float_write_space (top[2].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes))
		{
			ringb_float_write (top[2].jack.ring.i.l, input[4], nframes);
			ringb_float_write (top[2].jack.ring.i.r, input[5], nframes);
		}
		else
		{	
			// rb pathology
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[thread], 0, nframes * sizeof (float));
				memset (output[thread], 0, nframes * sizeof (float));
			}
			return;
		}
		
		// if enough accumulated in ring, fire dsp
		if ((ringb_float_read_space (top[2].jack.ring.i.l) >= top[2].hold.size.frames) &&
			(ringb_float_read_space (top[2].jack.ring.i.r) >= top[2].hold.size.frames))
			sem_post (&top[2].sync.buf.sem);

	} else
#endif
	for(thread=0; thread<threadno; thread++) 
	{
		int l=2*thread, r = 2*thread+1;
		if ((ringb_float_read_space (top[thread].jack.ring.o.l) >= nframes)
			&& (ringb_float_read_space (top[thread].jack.ring.o.r) >= nframes))
		{
			/*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes);
			ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/
			ringb_float_read (top[thread].jack.ring.o.l, output[l], nframes);
			ringb_float_read (top[thread].jack.ring.o.r, output[r], nframes);
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[2*thread  ], 0, nframes * sizeof (float));
				memset (output[2*thread+1], 0, nframes * sizeof (float));
			}
			return;
		}

		// input: copy from port to ring
		if ((ringb_float_write_space (top[thread].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[thread].jack.ring.i.r) >= nframes))
		{
			if (diversity.flag && (thread == 0)) {
				if ((ringb_float_write_space (top[2].jack.ring.i.l) >= nframes)
					&& (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes))
				{
					REAL *l0 = input[0];
					REAL *r0 = input[1];
					REAL *l2 = input[4];
					REAL *r2 = input[5];
					for (i=0;i<nframes;i++) {
						COMPLEX A = Cmplx(l0[i],r0[i]);
						COMPLEX B = Cmplx(l2[i],r2[i]);
						A = Cscl(Cadd(A,Cmul(B,diversity.scalar)),diversity.gain);
						ringb_float_write (top[0].jack.ring.i.l, &A.re, 1);
						ringb_float_write (top[0].jack.ring.i.r, &A.im, 1);
					}
					/*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes);
					ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/
				} else {
					// rb pathology
					//reset_system_audio(nframes);
					for(thread=0;thread<threadno;thread++) 
					{
						memset (output[2*thread  ], 0, nframes * sizeof (float));
						memset (output[2*thread+1], 0, nframes * sizeof (float));
					}
					return;
				}
			} else {
				ringb_float_write (top[thread].jack.ring.i.l, input[l], nframes);
				ringb_float_write (top[thread].jack.ring.i.r, input[r], nframes);
				/*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes);
				ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/
			}
		}
		else
		{	
			// rb pathology
			//reset_system_audio(nframes);
			for(thread=0;thread<threadno;thread++) 
			{
				memset (output[2*thread  ], 0, nframes * sizeof (float));
				memset (output[2*thread+1], 0, nframes * sizeof (float));
			}
			return;
		}
		
		// if enough accumulated in ring, fire dsp
		if ((ringb_float_read_space (top[thread].jack.ring.i.l) >= top[thread].hold.size.frames) &&
			(ringb_float_read_space (top[thread].jack.ring.i.r) >= top[thread].hold.size.frames))
			sem_post (&top[thread].sync.buf.sem);
	}
}
Пример #5
0
int main(int argc, char *argv[])
{
  int n_elements = 61;
  int n_processors = 10;

  // First calculate how much work to give to each process.
  // Really, this is just a dummy example. Each child will just
  // do some meaningless calculations as an example.
  int n_per_processor = n_elements / n_processors;

  int n_remaining = n_elements % n_processors;

  int node_start = 0;
  int node_end;
  printf("\n");

  // Here we read the key for the shared memory. This will be availble
  // to all clients so they can attach to shared memory.
  // Remember, each child will inherit an exact copy of the stack and
  // heap.
  //
  //
  int shm_fd = shm_open("/wikastarea1", O_RDWR, 0755);
  if (shm_fd < 0)
  {
    perror("shm_open");
    exit(0);
  }
  void *mptr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
                   MAP_SHARED, shm_fd,   0x0);
  if (mptr == MAP_FAILED)
  {
    perror("mmap");
    exit(0);
  }

  shdata_t *shdata = (shdata_t *) mptr;

  sem_t *sem1 = sem_open("/wikassem1", 0);
  if (sem1 == SEM_FAILED)
  {
    perror("sem_open sem1");
    exit(0);
  }

  sem_t *sem2 = sem_open("/wikassem2", 0);
  if (sem2 == SEM_FAILED)
  {
    perror("sem_open sem2");
    exit(0);
  }


  int count = 0;
  for (int i=0; i < 100; i++)
  {
    sem_wait(sem2);

    printf("Damn! the pot is empty!\n");
    for (int j=0;  j < 10; j++)
    {
      shdata->values[j] = 1.0;
      printf("producing %d\n", ++count);
    }

    sem_post(sem1);
  }

}
Пример #6
0
static gsize get_mpeg2ts_segment (RequestData *request_data, EncoderOutput *encoder_output, gchar **buf)
{
    GstClockTime timestamp;
    gint number;
    guint64 year, month, mday, hour, sequence, duration, rap_addr, max_age;
    GstClockTime us; /* microseconds */
    struct tm tm;
    gchar date[20], *header, *path, *file, *cache_control;
    gsize buf_size;
    GError *err = NULL;
    struct timespec ts;

    number = sscanf (request_data->uri, "/%*[^/]/encoder/%*[^/]/%04lu%02lu%02lu%02lu/%lu_%lu_%lu.ts$",
            &year, &month, &mday, &hour, &us, &sequence, &duration);
    if (number != 7) {
        GST_WARNING ("uri not found: %s", request_data->uri);
        *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    sprintf (date, "%04lu-%02lu-%02lu %02lu:00:00", year, month, mday, hour);
    memset (&tm, 0, sizeof (struct tm));
    strptime (date, "%Y-%m-%d %H:%M:%S", &tm);
    tm.tm_isdst = daylight;
    timestamp = mktime (&tm) * 1000000 + us;

    /* read from memory */
    if (clock_gettime (CLOCK_REALTIME, &ts) == -1) {
        GST_ERROR ("get_mpeg2ts_segment clock_gettime error: %s", g_strerror (errno));
        *buf = g_strdup_printf (http_500, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    ts.tv_sec += 2;
    while (sem_timedwait (encoder_output->semaphore, &ts) == -1) {
        if (errno == EINTR) {
            continue;
        }
        GST_ERROR ("get_mpeg2ts_segment sem_timedwait failure: %s", g_strerror (errno));
        *buf = g_strdup_printf (http_500, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    /* seek gop */
    rap_addr = encoder_output_gop_seek (encoder_output, timestamp);
    if (rap_addr != G_MAXUINT64) {
        /* segment found, send it */
        gsize gop_size;

        gop_size = encoder_output_gop_size (encoder_output, rap_addr);
        cache_control = g_strdup_printf ("max-age=%lu", encoder_output->dvr_duration);
        header = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "video/mpeg", gop_size, cache_control, "");
        g_free (cache_control);
        *buf = g_malloc (strlen (header) + gop_size);
        memcpy (*buf, header, strlen(header));
        if (rap_addr + gop_size + 12 < encoder_output->cache_size) {
            memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, gop_size);

        } else {
            gint n;

            n = encoder_output->cache_size - rap_addr - 12;
            if (n > 0) {
                memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, n);
                memcpy (*buf + strlen (header) + n, encoder_output->cache_addr, gop_size - n);

            } else {
                GST_WARNING ("nnnnn: n < 0 %d", n);
                memcpy (*buf + strlen (header), encoder_output->cache_addr - n, gop_size);
            }
        }
        buf_size = strlen (header) + gop_size;
        g_free (header);

    } else {
        buf_size = 0;
    }
    sem_post (encoder_output->semaphore);

    /* buf_size == 0? segment not found in memory, read frome dvr directory */
    if (buf_size == 0) {
        path = g_strdup_printf ("%s/%04lu%02lu%02lu%02lu/%010lu_%lu_%lu.ts",
                encoder_output->record_path,
                year, month, mday, hour, us, sequence, duration);
        if (!g_file_get_contents (path, &file, &buf_size, &err)) {
            g_error_free (err);
            GST_WARNING ("segment not found: %s", request_data->uri);
            *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
            buf_size = strlen (*buf);

        } else {
            max_age = encoder_output->dvr_duration - (g_get_real_time () - timestamp) / 1000000;
            cache_control = g_strdup_printf ("max-age=%lu", max_age);
            header = g_strdup_printf (http_200,
                    PACKAGE_NAME,
                    PACKAGE_VERSION,
                    "video/mpeg",
                    buf_size,
                    cache_control,
                    "");
            g_free (cache_control);
            *buf = g_malloc (buf_size + strlen (header));
            memcpy (*buf, header, strlen (header));
            memcpy (*buf + strlen (header), file, buf_size);
            buf_size += strlen (header);
            g_free (header);
            g_free (file);
        }
        g_free (path);
    }

    return buf_size;
}
Пример #7
0
// Serves as a global method to trigger reinitialization
// and as a function that can be provided to signal().
void reinit_signal_handler(int /*signal*/) {
    sem_post(&reinit);
}
Пример #8
0
int service_engine(char *addr, int port)
{
    int i;
    if(MAX_TASK_NUM > 0)
    {
        for (i = 0; i < MAX_TASK_NUM; i++)
        {
            sem_init(&event[i], 0, 0);
            int temp = i;
           if (pthread_create(&thread_id[i], NULL, (void *)handle_requests, (void *)temp) != 0)
            {
                printf("pthread_create error, %s:%d\n",__FILE__, __LINE__);
                exit(-1);
            }

        }
    }
    /* 
     * command line console
     */

    init_mdb();

    ServiceHandler h = -1;
    initialize_service(addr,port);
    while(1)
    {
        h = service_start();
        //        handle_request(h);  
        task_node_t *tnode = (task_node_t *)malloc( sizeof(task_node_t));
        tnode->buf_size = MAX_BUF_LEN;
        if (receive_data (h, tnode->buf, &(tnode->buf_size)) == 0)
        {
            service_stop(h);
            continue;
        }

        if (MAX_TASK_NUM > 0)
        {
            tnode->req = h;
            int i = random_int(MAX_TASK_NUM);
            /* put tnode into task_list */
            if (task_list[i] == NULL)
            {
                task_list[i] = tnode;
                tnode->next = NULL;
                tnode->last = tnode;
            }
            else
            {
                task_node_t *p = task_list[i];
                p->last->next = tnode;
                p->last = tnode;
                tnode->next = NULL;
            }
            sem_post(&event[i]);

            //        service_stop(h); 
        }
        else 
        {
            handle_one_request(h, tnode->buf, tnode->buf_size);
            free(tnode);
        }
    }
    shutdown_service();
    close_mdb();
    if (MAX_TASK_NUM > 0 )
    {
        for (i = 0; i< MAX_TASK_NUM; i++)
        {
            task_node_t *p = task_list[i];
            task_node_t *q;
            while (p)
            {
                q = p->next;
                free(p);
                p = q;
            }
        }
    }
    return 0;
}
Пример #9
0
void threadfunc()
{
        printf("Hello from threadfunc!\n");
        sleep(3);
        sem_post(&g_sema);
}
Пример #10
0
 virtual void readDone(uint32_t v) {
   fprintf(stderr, "readDone %d\n", v);
   sem_post(&read_sem);
 }
/*
 * La cola RR solo la agregamos por compatibilidad,
 * siempre va a ser un puntero a NULL.
 */
uint32_t atender_peticion_orquestador(uint32_t cliente, t_stream *pedido, t_queue_rr *cola_rr){

	/*t_stream *pedido;
	recibir(cliente, (void*)&pedido);
*/
	t_header header;
	deserializar_header(pedido, &header);
	int32_t pos_payload = sizeof(t_header);
	//char personajeElegido;
	switch (header.type){

	case HANDSHAKE_NUEVO_NIVEL:{

		uint32_t nro_nivel;
		uint32_t puerto;
		t_stream *payload = get_payload(pedido);
		memcpy(&nro_nivel,&payload[0],4);
		memcpy(&puerto,&payload[4],4);

		t_planificador *nodo_planificador;
		nodo_planificador = get_nodo_nivel(nro_nivel);
		//log_debug(logger_orq, "Hand_nuevo_nivel: dir nodo_planificador = %d", nodo_planificador);
		if(nodo_planificador == NULL){
			nodo_planificador = malloc(sizeof(t_planificador));
			nodo_planificador->tid=malloc(sizeof(pthread_t));
			nodo_planificador->nivel.direccion = malloc(sizeof(struct sockaddr_in));

			log_info(logger_orq, "Handshake_nuevo_nivel: Nueva conexión, nivel %d.", nro_nivel);
			completar_datos_nivel(nro_nivel, cliente, nodo_planificador);

			nodo_planificador->planificador.descriptor = 0;
			(nodo_planificador->nivel.direccion)->sin_port=htons(puerto);
			list_mutex_add(planificadores, (void*) nodo_planificador);
			sem_post(&semaforo_nodos_nuevos);
			free(pedido);
			return EXIT_SUCCESS;
		}
		log_info(logger_orq, "Se reconecta en nivel %d.", nro_nivel);
		completar_datos_nivel(nro_nivel, cliente, nodo_planificador);
		(nodo_planificador->nivel.direccion)->sin_port=htons(puerto);
		free(pedido);
		return EXIT_SUCCESS;
		}

	case HANDSHAKE_NUEVO_PJ:{

		int8_t simbolo_pj;
		t_stream *payload =get_payload(pedido);
		simbolo_pj = (int8_t)payload[0];
		log_info(logger_orq, "Handshake_nuevo_pj: Nueva conexión, pj %c", simbolo_pj);
		t_personaje_finalizado *pj;
		int pos_pj;
		pos_pj = get_pos_pj_finalizado(simbolo_pj);

		//Si todavía no está en la lista lo metemos.
		if(pos_pj == -1){
			log_debug(logger_orq, "Handshake_nuevo_pj: El pj no existía así que lo guardo en listo personajes_finalizados.");
			pj = malloc(sizeof(t_personaje_finalizado));
			pj->simbolo_pj = simbolo_pj;
			pj->termino_plan_de_niveles = false;
			log_debug(logger_orq, "Handshake_nuevo_pj: Guardo: Simbolo = %c  bool_fin = %d", pj->simbolo_pj, pj->termino_plan_de_niveles);
			list_mutex_add(personajes_finalizados, (void*)pj);
			t_personaje_finalizado *test_pj = list_mutex_get(personajes_finalizados, 0);
			log_debug(logger_orq,"Handshake_nuevo_pj: Guardé simbolo = %c, bool_fin = %d ", test_pj->simbolo_pj, test_pj->termino_plan_de_niveles);
		}
		else{
			pthread_mutex_lock(&personajes_finalizados->mutex);
			pj = list_get(personajes_finalizados->list, pos_pj);
			pj->termino_plan_de_niveles = false;
			pthread_mutex_unlock(&personajes_finalizados->mutex);
		}
		t_stream *stream_senial_ok;
		stream_senial_ok  = serializar_senial(OK);
		log_debug(logger_orq, "Handshake_nuevo_pj: Envío OK al pj recién conectado");
		enviar(cliente, stream_senial_ok);
		free(stream_senial_ok);
		free(pedido);
		return EXIT_SUCCESS;


	}

	case SOLICITUD_DATOS_NIVEL:{

		t_stream *payload = get_payload(pedido);
		int8_t simbolo_pj = payload[0];
		int8_t nro_nivel = payload[1];
	    t_datos_nivel datos_nivel;
	    datos_nivel.direccion_nivel[0] = '\0';
	    datos_nivel.direccion_planificador[0]='\0';
	    int resultado = get_datos_nivel(nro_nivel, &datos_nivel);

	    //Si el nivel no existe o si todavía no se lanzó su planificador asociado.
	    if(resultado == EXIT_FAILURE){
	    	char cadena_vacia = 'a';
	        t_stream *stream_nivel_no_existe = serializar_solicitud(NO_EXISTE_EL_NIVEL, sizeof(cadena_vacia), (t_stream*)&cadena_vacia);
	        log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d pero el nivel aún no fue cargado.", simbolo_pj, nro_nivel);
	        enviar(cliente, (void*) stream_nivel_no_existe);
	        free(pedido);
	        free(stream_nivel_no_existe);
	        return EXIT_SUCCESS;
	    }
	   t_stream *stream_datos_nivel;
	   //En esta linea tira
	   stream_datos_nivel = serializar_datos_nivel(&datos_nivel);

	   log_debug(logger_orq,"Sol_datos_nivel: Datos del nivel solicitado: %s",datos_nivel.direccion_nivel);
	   log_debug(logger_orq, "Sol_datos_nivel: Datos del planificador solicitado: %s",datos_nivel.direccion_planificador);

	   log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d. Se responde con los datos solicitados.", simbolo_pj, nro_nivel);
	   enviar(cliente, stream_datos_nivel);
	    free(stream_datos_nivel);
	    free(pedido);

	    return EXIT_SUCCESS;
	}

	case RECURSOS_LIBERADOS:{
			//Los recursos vienen en un string con formato HHHHFFFFMMMM,
			char *recursos = (char*) &pedido[pos_payload];
			uint32_t nro_nivel = get_nro_nivel(cliente);
			log_debug(logger_orq,"Recursos_liberados: Obteniendo socket_pair del planificador.");
			int32_t socket_pair_planificador = get_socket_pair_planificador(nro_nivel);
			log_debug(logger_orq,"Recursos_liberados: El socket pair es: %d", socket_pair_planificador);
			int32_t indice_recurso = 0;
			int8_t personaje_recurso[2];
			int8_t personaje_nro_nivel[2];
			log_info(logger_orq, "Recursos_liberados: El nivel %d liberó los recursos: %s ", nro_nivel, recursos);
			while(recursos[indice_recurso] != '\0'){
				//La función pasa a un pj de bloqueados a personajes_listos.
				int8_t simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel);
				if (simbolo_pj_desbloqueado>0)
					log_info(logger_orq,"Recursos_liberados: PJ elegido para desbloquear: %c, recurso: %c", simbolo_pj_desbloqueado, recursos[indice_recurso]);
				else
					log_info(logger_orq,"Recursos_liberados: Ningún pj esperaba el recurso %c", recursos[indice_recurso]);

				//Si no hay un pj que necesite ese recurso, en lugar del símbolo del pj envía -1.
				personaje_recurso[0] = simbolo_pj_desbloqueado;
				personaje_recurso[1] = recursos[indice_recurso];
				t_stream *stream_pj_recurso = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_recurso);

				//Aviso al planificador para que lo saque de personajes_listo y lo ponga en cola_rr
				if(simbolo_pj_desbloqueado != -1){
					personaje_nro_nivel[0] = simbolo_pj_desbloqueado;
					personaje_nro_nivel[1] = (int8_t) nro_nivel;
					log_debug(logger_orq,"Recursos_liberados: Envio al planificador pj: %c, nro_nivel: %d", personaje_nro_nivel[0], personaje_nro_nivel[1]);
					t_stream *stream_pj_nro_nivel = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_nro_nivel);
					int test_result_sock_pair = enviar(socket_pair_planificador, (void*) stream_pj_nro_nivel);
					if(test_result_sock_pair == EXIT_FAILURE)
						log_error(logger_orq,"Recursos_liberados: Error al enviar mensaje al socket_pair (nro %d)del planificador ", socket_pair_planificador);
					else
						log_debug(logger_orq,"Recursos_liberados: Se envió el msj al socket_pair nro %d", socket_pair_planificador);

					free(stream_pj_nro_nivel);
				}

				log_debug(logger_orq,"Recursos_liberados: Envio al nivel pj: %c, recurso: %c  ", personaje_recurso[0], personaje_recurso[1]);
				enviar(cliente, (void*)stream_pj_recurso);
				free(stream_pj_recurso);
				//simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel);
				indice_recurso++;

			}

			free(pedido);
			return EXIT_SUCCESS;
		}

	case FIN_PLAN_NIVELES:{
		t_stream *payload = get_payload(pedido);
		int8_t simbolo_pj = payload[0];
		log_info(logger_orq,"Fin_plan_niveles: El pj %c terminó su plan de niveles ", simbolo_pj);
		int pos_pj = get_pos_pj_finalizado(simbolo_pj);
		log_debug(logger_orq,"Fin_plan_niveles: Pos del pj finalizado = %d", pos_pj);
		t_personaje_finalizado *pj_finalizado = list_mutex_get(personajes_finalizados, pos_pj);
		pj_finalizado->termino_plan_de_niveles = true;
		if(todos_los_pj_terminaron()){

			log_info(logger_orq,"Fin_plan_niveles: Todos los pj finalizaron su plan de niveles.");

			solicitar_fin_ejecucion_planificadores();

			//Variable global que está en el while principal de todos los hilos.
			keep_running = false;
			estado_plataforma = false;
			sem_post(&semaforo_nodos_nuevos);
		}
		log_debug(logger_orq, "Fin_plan_niveles: FIN_PLAN_DE_NIVELES,case: retorno EXIT_SUCCESS;");
		free(pedido);
		return EXIT_SUCCESS;
	}
	case RECOVERY:{
		log_info(logger_orq, "Llegó pedido de recovery.");
		int8_t * personajesEnDeadlock = (int8_t*) &pedido[pos_payload];
		printf("Llegó string: %s \n", personajesEnDeadlock);
		log_info(logger_orq, "Los PJs involucrados en el interbloqueo son %s", personajesEnDeadlock);
		t_personaje_listo *personajeElegido;
		int index_pj = 0;

		//Este while es solo por contención, se supone el pj[0] siempre va a estar bloqueado.
		while(personajesEnDeadlock[index_pj] != '\0'){
			int8_t simbolo_pj = personajesEnDeadlock[index_pj];
			personajeElegido= list_remove_personaje(personajes_bloqueados, simbolo_pj);

			if(personajeElegido != NULL){
				log_info(logger_orq, "Recovery: Se da muerte al pj %c y se notifica al nivel.", personajeElegido->simbolo_pj);
				notificarPersonajeAsesinado(cliente, personajeElegido);
					if(index_pj != 0)
						log_info(logger_orq, "El pj asesinado estaba en la posición %d", index_pj);
				free(pedido);
				return EXIT_SUCCESS;
			}
			index_pj++;

		}
		log_error(logger_orq, "No se encontró ningún personaje para asesinar.");
		free(pedido);
		return EXIT_SUCCESS;


	}
	case HUBO_UNA_DESCONEXION:{
		log_info(logger_orq, "Hubo una desconexión.");
		free(pedido);
		return EXIT_SUCCESS;
	}


		log_warning(logger_orq, "Hubo_desconexión: Recibo petición de tipo desconocida");

		return EXIT_SUCCESS;

	}



/*
	case RECOVERY:{//todo: agregar al serializador
		//todo: matar_personaje, func q devuelve el nombre de pj asesinado.
		//char *nombre_personaje = matar_personaje();
		notificacion_pj_asesinado(cliente, nombre_personaje);
		free(nombre_personaje);
		free(pedido); //todo: poner free pedido fuera de atender_peticion()?
		return EXIT_SUCCESS;

	}*/



	return EXIT_SUCCESS;
}
Пример #12
0
 virtual void writeDone(uint32_t v) {
   fprintf(stderr, "writeDone %d\n", v);
   sem_post(&write_sem);
 }
Пример #13
0
static inline void cgi_semgive(void)
{
  sem_post(&g_cgisem);
}
Пример #14
0
 virtual void bscanGet(uint64_t v) {
     printf("bscanGet: %llx\n", (long long)v);
     sem_post(&sem_bscan);
 }
Пример #15
0
static int process_callback( jack_nframes_t nframes, void *arg )
{
	int c;
	jack_handle_t* handle = (jack_handle_t*)arg;
	size_t to_read = nframes;

	for(c=0; c<handle->channels; ++c)
		handle->ports_buf[c] =
			jack_port_get_buffer(handle->ports[c], nframes);

	/* One ringbuffer to rule them all, getting interleaved data piecewise
	   and appending to non-interleaved buffers. */
	while(to_read)
	{
		/* Need to read into temporary storage, then deinterleave to JACK
		   buffers. */
		size_t got_piece;
		size_t avail_piece;
		size_t piece = to_read > handle->procbuf_frames
		?	handle->procbuf_frames
		:	to_read;
		/* Ensure we get only full PCM frames by checking available byte count
		   and reducing expectation. */
		avail_piece = jack_ringbuffer_read_space(handle->rb)/handle->framesize;
		got_piece = jack_ringbuffer_read( handle->rb
		,	handle->procbuf, (avail_piece > piece ? piece : avail_piece)
		*	handle->framesize ) / handle->framesize;
		debug2( "fetched %"SIZE_P" frames from ringbuffer (wanted %"SIZE_P")"
		,	(size_p)got_piece, (size_p)piece );
		/* If this is the last piece, fill up, not time to wait. */
		if(to_read > piece)
			piece = got_piece; /* We got further loop cycle(s) to get the rest. */
		else
		{
			if(piece > got_piece)
			{
				debug("filling up with zeros");
				bzero( handle->procbuf+got_piece*handle->framesize
				,	(piece-got_piece)*handle->framesize );
			}
		}
		/* Now extract the pieces for the channels. */
		for (c=0; c < handle->channels; ++c)
		{
			size_t n;
			jack_default_audio_sample_t *dst = handle->ports_buf[c];
			if(handle->encoding == MPG123_ENC_FLOAT_32)
			{
				float* src = (float*)handle->procbuf;
				for(n=0; n<piece; ++n)
					*(dst++) = src[(n*handle->channels)+c];
			}
			else /* MPG123_ENC_FLOAT_64 */
			{
				double* src = (double*)handle->procbuf;
				for(n=0; n<piece; ++n)
					*(dst++) = src[(n*handle->channels)+c];
			}
			/* Store output buffer offset. */
			handle->ports_buf[c] = dst;
		}
		/* Give the writer a hint about the time passed. */
		sem_post(&handle->sem);
		to_read -= piece;
	}
	/* Success*/
	return 0;
}
Пример #16
0
void threadfunc1()
{
        printf("Hello from threadfunc1\n");
        sleep(5);
        sem_post(&g_sema);
}
Пример #17
0
static GstClockTime send_chunk (EncoderOutput *encoder_output, RequestData *request_data)
{
    HTTPStreamingPrivateData *priv_data;
    gint64 current_gop_end_addr, tail_addr;
    gint32 ret;
    struct timespec ts;

    priv_data = request_data->priv_data;

    if (clock_gettime (CLOCK_REALTIME, &ts) == -1) {
        GST_ERROR ("send_chunk clock_gettime error: %s", g_strerror (errno));
        return 100 * GST_MSECOND + g_random_int_range (1, 1000000);
    }
    ts.tv_sec += 2;
    while (sem_timedwait (encoder_output->semaphore, &ts) == -1) {
        if (errno == EINTR) {
            continue;
        }
        GST_ERROR ("send_chunk sem_timedwait failure: %s", g_strerror (errno));
        return 100 * GST_MSECOND + g_random_int_range (1, 1000000);
    }
    tail_addr = *(encoder_output->tail_addr);
    current_gop_end_addr = get_current_gop_end (encoder_output, priv_data);

    if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) {
        /* completly send a chunk, prepare next. */
        priv_data->send_position += priv_data->send_count - priv_data->chunk_size_str_len - 2;
        if (priv_data->send_position == encoder_output->cache_size) {
            priv_data->send_position = 0;
        }
        g_free (priv_data->chunk_size_str);
        priv_data->chunk_size_str_len = 0;
        priv_data->chunk_size = 0;
    }

    if (priv_data->send_position == current_gop_end_addr) {
        /* next gop. */
        priv_data->rap_addr = current_gop_end_addr;
        if (priv_data->send_position + 12 < encoder_output->cache_size) {
            priv_data->send_position += 12;

        } else {
            priv_data->send_position = priv_data->send_position + 12 - encoder_output->cache_size;
        }
        current_gop_end_addr = get_current_gop_end (encoder_output, priv_data);
    }
    sem_post (encoder_output->semaphore);

    if (priv_data->chunk_size == 0) {
        if (current_gop_end_addr == -1) {
            /* current output gop. */
            if ((tail_addr - priv_data->send_position) > 16384) {
                priv_data->chunk_size = 16384;

            } else if (tail_addr > priv_data->send_position) {
                /* send to tail. */
                priv_data->chunk_size = tail_addr - priv_data->send_position;

            } else if (tail_addr == priv_data->send_position) {
                /* no data available, wait a while. */
                return 100 * GST_MSECOND + g_random_int_range (1, 1000000);

            } else if ((encoder_output->cache_size - priv_data->send_position) > 16384) {
                priv_data->chunk_size = 16384;

            } else {
                priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position;
            }

        } else {
            /* completely output gop. */
            if ((current_gop_end_addr - priv_data->send_position) > 16384) {
                priv_data->chunk_size = 16384;

            } else if (current_gop_end_addr > priv_data->send_position) {
                /* send to gop end. */
                priv_data->chunk_size = current_gop_end_addr - priv_data->send_position;

            } else if (current_gop_end_addr == priv_data->send_position) {
                /* no data available, wait a while. */
                return 100 * GST_MSECOND + g_random_int_range (1, 1000000); //FIXME FIXME

            } else {
                /* send to cache end. */
                priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position;
            }
        }
        priv_data->chunk_size_str = g_strdup_printf ("%x\r\n", priv_data->chunk_size);
        priv_data->chunk_size_str_len = strlen (priv_data->chunk_size_str);
        priv_data->send_count = 0;
    }

    /* send data. */
    ret = send_data (encoder_output, request_data);
    if (ret == -1) {
        return GST_CLOCK_TIME_NONE;

    } else {
        priv_data->send_count += ret;
        request_data->bytes_send += ret;
    }
    if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) {
        /* send complete, wait 10 ms. */
        return 10 * GST_MSECOND + g_random_int_range (1, 1000000);

    } else {
        /* not send complete, blocking, wait 200 ms. */
        return 200 * GST_MSECOND + g_random_int_range (1, 1000000);
    }
}
Пример #18
0
Файл: 21-1.c Проект: 1587/ltp
int main(void)
{
	int ret, status;
	pid_t child, ctl;
	pthread_t th;

	output_init();

	ctl = getpid();

	/* Initialize the semaphore */
	sem = sem_open("/fork_21_1", O_CREAT, O_RDWR, 0);

	if (sem == SEM_FAILED)
		UNRESOLVED(errno, "Failed to open the semaphore");

	sem_unlink("/fork_21_1");

	/* Create thread */
	ret = pthread_create(&th, NULL, threaded, &ctl);

	if (ret != 0)
		UNRESOLVED(ret, "Failed to create the thread");

	/* Create the child */
	child = fork();

	if (child == -1)
		UNRESOLVED(errno, "Failed to fork");

	/* We post the semaphore twice */
	do {
		ret = sem_post(sem);
	} while (ret != 0 && errno == EINTR);

	if (ret != 0)
		UNRESOLVED(errno, "Failed to post the semaphore");

	/* child */
	if (child == 0) {
		/* sleep a little while to let the thread execute in case it exists */
		sleep(1);

		/* We're done */
		exit(PTS_PASS);
	}

	/* Parent joins the child */
	ctl = waitpid(child, &status, 0);

	if (ctl != child)
		UNRESOLVED(errno, "Waitpid returned the wrong PID");

	if (!WIFEXITED(status) || WEXITSTATUS(status) != PTS_PASS)
		FAILED("Child exited abnormally");

	/* Destroy everything */
	ret = sem_close(sem);

	if (ret != 0)
		UNRESOLVED(errno, "Failed to close the semaphore");

	ret = pthread_join(th, NULL);

	if (ret != 0)
		UNRESOLVED(ret, "Failed to join the thread in parent");

#if VERBOSE > 0
	output("Test passed\n");
#endif
	PASSED;
}
Пример #19
0
void stdout_stats_and_post_sem_cb(struct rb_mse_api *rb_mse, struct rb_mse_stats *stats, void *_sem)
{
	sem_t * sem = _sem;
	stdout_stats_cb(rb_mse,stats,NULL);
	sem_post(sem);
}
static int stream_transfer(struct stream_transfer *stream_transfer)
{

	struct dev_stream *stream_sender;
	struct dev_stream *stream_receiver;
	int size_transfer = 0;
	int ret   =0;
	int exit_flag   =0;
	int i   =0;
	short* Srcptr;
	short* Drcptr;

	stream_sender = stream_transfer->stream_sender;
	stream_receiver = stream_transfer->stream_receiver;
	size_transfer = stream_sender->buf_size;


#ifdef  START_ZERO_BUFFER
	/* 消除开头杂音 */
	memset(stream_sender->buf, 0, stream_sender->buf_size);
	pcm_write(stream_receiver->dev, stream_sender->buf, stream_sender->buf_size);
#endif

	while( 1 ){
		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		ret = pcm_read(stream_sender->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			exit_flag = 1;
			ALOGE("err: read codec err:%s, ret=%d", strerror(errno), ret);
			break;
		}

		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		ret = pcm_write(stream_receiver->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			exit_flag = 1;
			ALOGE("err: write pcm err:%s, ret=%d", strerror(errno), ret);
		}

		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		if (stream_transfer->record_flag == 1){
			//是上行,还是下行.
			if (stream_transfer->voice_direction == UPSTREAM){
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwriteup%record_data.record_lenth));
				if(record_data.lenwriteup >= record_data.lenwritedown)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{
					int i;
					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = (*Drcptr + *Srcptr++)/2;
					}
					record_data.lenwrite += size_transfer;
//				        sem_post(&sem_record);
				}
				record_data.lenwriteup += size_transfer;
				//ALOGD("stream is upload");
			} else {
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwritedown%record_data.record_lenth));
				if(record_data.lenwritedown >= record_data.lenwriteup)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{

					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = ((int)*Drcptr + (int)(*Srcptr++))/2;
					}
					record_data.lenwrite += size_transfer;
//				        sem_post(&sem_record);
				}
				record_data.lenwritedown += size_transfer;
				//ALOGD("stream is download");
			}	
		        sem_post(&sem_record);
		}

		//ALOGD("pcm running ... , type=%d ",stream_sender->type);
		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}
	}
	return 0;
}
Пример #21
0
DttSP_EXP void
Audio_Callback (float *input_l, float *input_r, float *output_l,
	float *output_r, unsigned int nframes, int thread)
{
	BOOLEAN b = reset_em;
	int i;

        i=thread;
	if (top[i].susp)
	{
		memset (output_l, 0, nframes * sizeof (float));
		memset (output_r, 0, nframes * sizeof (float));
		return;
	}

	if (b)
	{
		//fprintf(stdout,"Audio_Callback: call reset_system_audio\n"), fflush(stdout);
		reset_system_audio(nframes);
		memset (output_l, 0, nframes * sizeof (float));
		memset (output_r, 0, nframes * sizeof (float));
		return;
    }

	//for (i=0; i<2; i++) 
	//{
		if ((ringb_float_read_space (top[i].jack.ring.o.l) >= nframes)
			&& (ringb_float_read_space (top[i].jack.ring.o.r) >= nframes))
		{
			if (top[i].state == RUN_PLAY)
			{
				ringb_float_read (top[i].jack.auxr.o.l, output_l, nframes);
				ringb_float_read (top[i].jack.auxr.o.r, output_r, nframes);
				ringb_float_read (top[i].jack.ring.o.l, output_l, nframes);
				ringb_float_read (top[i].jack.ring.o.r, output_r, nframes);
			}
			else
			{
				ringb_float_read_advance (top[i].jack.auxr.o.l, nframes);
				ringb_float_read_advance (top[i].jack.auxr.o.r, nframes);
				ringb_float_read_advance (top[i].jack.ring.o.l, nframes);
				ringb_float_read_advance (top[i].jack.ring.o.r, nframes);

			}
		}
		else
		{	// rb pathology
			//fprintf(stdout,"Audio_Callback-2: rb out pathology\n"), fflush(stdout);
//			reset_system_audio(nframes);
//			memset (output_l, 0, nframes * sizeof (float));
//			memset (output_r, 0, nframes * sizeof (float));
		}

		// input: copy from port to ring
		if ((ringb_float_write_space (top[i].jack.ring.i.l) >= nframes)
			&& (ringb_float_write_space (top[i].jack.ring.i.r) >= nframes))
		{
			ringb_float_write (top[i].jack.ring.i.l, (float *) input_l, nframes);
			ringb_float_write (top[i].jack.ring.i.r, (float *) input_r, nframes);
			ringb_float_write (top[i].jack.auxr.i.l, (float *) input_l, nframes);
			ringb_float_write (top[i].jack.auxr.i.r, (float *) input_r, nframes);
		}
		else
		{	// rb pathology
			//fprintf(stdout,"Audio_Callback-3: rb in pathology\n"), fflush(stdout);
//			reset_system_audio(nframes);
//			memset (output_l, 0, nframes * sizeof (float));
//			memset (output_r, 0, nframes * sizeof (float));
		}

		// if enough accumulated in ring, fire dsp
		if (ringb_float_read_space (top[i].jack.ring.i.l) >= top[i].hold.size.frames)
			sem_post (&top[i].sync.buf.sem);
	//}
}
Пример #22
0
 virtual void reportMemoryTraffic(uint64_t words){
   //fprintf(stderr, "reportMemoryTraffic: words=%"PRIx64"\n", words);
   mtCnt = words;
   sem_post(&mtSem);
 }
Пример #23
0
static uint16_t netclose_interrupt(FAR struct net_driver_s *dev,
                                   FAR void *pvconn, FAR void *pvpriv,
                                   uint16_t flags)
{
#ifdef CONFIG_NET_SOLINGER
  FAR struct tcp_close_s *pstate = (FAR struct tcp_close_s *)pvpriv;
#endif
  FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;

  DEBUGASSERT(conn != NULL);

  nllvdbg("conn: %p flags: %04x\n", conn, flags);

  /* TCP_DISCONN_EVENTS:
   *   TCP_CLOSE:    The remote host has closed the connection
   *   TCP_ABORT:    The remote host has aborted the connection
   *   TCP_TIMEDOUT: The remote did not respond, the connection timed out
   *   NETDEV_DOWN:  The network device went down
   */

  if ((flags & TCP_DISCONN_EVENTS) != 0)
    {
      /* The disconnection is complete */

#ifdef CONFIG_NET_SOLINGER
      /* pstate non-NULL means that we are performing a LINGERing close. */

      if (pstate)
        {
          /* Wake up the waiting thread with a successful result */

          pstate->cl_result = OK;
          goto end_wait;
        }

      /* Otherwise, nothing is waiting on the close event and we can perform
       * the completion actions here.
       */

      else
#endif
        {
          /* Free connection resources */

          tcp_free(conn);

          /* Stop further callbacks */

          flags = 0;
        }
    }

#ifdef CONFIG_NET_SOLINGER
  /* Check for a timeout. */

  else if (pstate && close_timeout(pstate))
    {
      /* Yes.. Wake up the waiting thread and report the timeout */

      nlldbg("CLOSE timeout\n");
      pstate->cl_result = -ETIMEDOUT;
      goto end_wait;
    }

#endif /* CONFIG_NET_SOLINGER */

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  /* Check if all outstanding bytes have been ACKed */

  else if (conn->unacked != 0 || !sq_empty(&conn->write_q))
    {
      /* No... we are still waiting for ACKs.  Drop any received data, but
       * do not yet report TCP_CLOSE in the response.
       */

      dev->d_len = 0;
      flags = (flags & ~TCP_NEWDATA);
    }

#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */

  else
    {
      /* Drop data received in this state and make sure that TCP_CLOSE
       * is set in the response
       */

      dev->d_len = 0;
      flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE;
    }

  return flags;

#ifdef CONFIG_NET_SOLINGER
end_wait:
  pstate->cl_cb->flags = 0;
  pstate->cl_cb->priv  = NULL;
  pstate->cl_cb->event = NULL;
  sem_post(&pstate->cl_sem);

  nllvdbg("Resuming\n");
  return 0;
#endif
}
Пример #24
0
void *eng_vlog_thread(void *x)
{
    int ser_fd, modem_fd;
    int r_cnt, w_cnt, offset;
    int retry_num = 0;
    int dumpmemlen = 0;
    eng_dev_info_t* dev_info = (eng_dev_info_t*)x;

    ENG_LOG("eng_vlog thread start\n");

    /*open usb/uart*/
    ENG_LOG("eng_vlog open serial...\n");
    ser_fd = eng_open_dev(dev_info->host_int.dev_log, O_WRONLY);
    if(ser_fd < 0) {
        ENG_LOG("eng_vlog open serial failed, error: %s\n", strerror(errno));
        return NULL;
    }

    /*open vbpipe/spipe*/
    ENG_LOG("eng_vlog open SIPC channel...\n");
    do{
        modem_fd = open(dev_info->modem_int.log_chan, O_RDONLY);
        if(modem_fd < 0) {
            ENG_LOG("eng_vlog cannot open %s, error: %s\n", dev_info->modem_int.log_chan, strerror(errno));
            sleep(5);
        }

        if((++retry_num) > MAX_OPEN_TIMES) {
            ENG_LOG("eng_vlog SIPC open times exceed the max times, vlog thread stopped.\n");
            goto out;
        }
    }while(modem_fd < 0);

    ENG_LOG("eng_vlog put log data from SIPC to serial\n");
    while(1) {
        int split_flag = 0;

        if(g_armlog_enable) {
            sem_post(&g_armlog_sem);
        }
        sem_wait(&g_armlog_sem);

        memset(log_data, 0, sizeof(log_data));
        r_cnt = read(modem_fd, log_data, DATA_BUF_SIZE);
        if (r_cnt <= 0) {
            ENG_LOG("eng_vlog read no log data : r_cnt=%d, %s\n",  r_cnt, strerror(errno));
            continue;
        }

        // printf dump memory len
        dump_mem_len_print(r_cnt, &dumpmemlen);

        offset = 0; //reset the offset

        if((r_cnt%64==0) && dev_info->host_int.cali_flag && (dev_info->host_int.dev_type == CONNECT_USB))
            split_flag = 1;
        do {
            if(split_flag)
                w_cnt = write(ser_fd, log_data + offset, r_cnt-32);
            else
                w_cnt = write(ser_fd, log_data + offset, r_cnt);
            if (w_cnt < 0) {
                if(errno == EBUSY)
                    usleep(59000);
                else {
                    ENG_LOG("eng_vlog no log data write:%d ,%s\n", w_cnt, strerror(errno));

                    // FIX ME: retry to open
                    retry_num = 0; //reset the try number.
                    while (-1 == restart_gser(&ser_fd, dev_info->host_int.dev_log)) {
                        ENG_LOG("eng_vlog open gser port failed\n");
                        sleep(1);
                        retry_num ++;
                        if(retry_num > MAX_OPEN_TIMES) {
                            ENG_LOG("eng_vlog: vlog thread stop for gser error !\n");
                            sem_post(&g_armlog_sem);
                            return 0;
                        }
                    }
                }
            } else {
                r_cnt -= w_cnt;
                offset += w_cnt;
                split_flag = 0;
                //ENG_LOG("eng_vlog: r_cnt: %d, w_cnt: %d, offset: %d\n", r_cnt, w_cnt, offset);
            }
        } while(r_cnt > 0);
    }

out:
    ENG_LOG("eng_vlog thread end\n");
    if (modem_fd >= 0)
        close(modem_fd);
    close(ser_fd);

    return 0;
}
Пример #25
0
void TasksQueue::incrementTasksToProcess()
{
	sem_post(&tasksToBeProcessed);
}
Пример #26
0
int CDCWinProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{

	switch (message)
	{
		case MSG_CREATE:
			UI_Set_From_Handl( hWnd);
			UI_LoadRes();
			

			break;
		case MSG_PAINT:
			if(is_init_all==T)
			{
				U_SBtn_Flag=1;
				UI_InitFrom(hWnd);
				UI_Set_Device_State(0,0);
				sem_post(&Device_semt);
				SendLaneInfo("等待上班");
				is_init_all = F;
				if (GetUseAutoMan()==T)
				{
					SetTimer(hWnd, 10, 10);
				}
				else 
				{
					SetTimer(hWnd, 100, 100);
				}
			}
			break;
		case MSG_TIMER:
			 
			if(GetMoneyTimer()<=3)
			{
				CloseMoneyBox();
			}
			if (Getg_bWeiZhang())
			{
				Setg_bWeiZhangCount(Getg_bWeiZhangCount()+1);
				if (Getg_bWeiZhangCount()>=atoi(sys_ini.RushCancelTime))
				{
					Setg_Violation(1);
					AddMsgTotal_Violation();
					SendMessageWzCar(0);
					SetWorkSationEndWz();
					SetVideoAlarm(F);
					Setg_bWeiZhangCount(0);
					Setg_bWeiZhang(F);
				}
			}
			if ( GetCanTestPrinter( ))
			{
				TestPrintState();
			}
//			WF_TestICReader();
			updateTime( );
			CheckHourSend();
			SendTCOMsg(MSGTCO_NETWORK,"OK");
			AutoManHandl();
			break;
		case MSG_KEYDOWN:
			if (KeyDown)
			{
				WorkStation(KeyTran(wParam));
				echoic("wParam = <%d><%d>",wParam,KeyTran(wParam));
				KeyDown = F;
			}
			break;
		case MSG_KEYUP:
			KeyDown = T;
			break;
	case MSG_BAR_UP:
		echoic("MSG_BAR_UPMSG_BAR_UPMSG_BAR_UPMSG_BAR_UPMSG_BAR_UP");
			G_CurrentSystemDevStatus.TongGuoLine = 1;
			PassLineUP();
			break;
		case MSG_BAR_DOWN:
			G_CurrentSystemDevStatus.TongGuoLine = 0;
			PassLineDown();
			break;
		case MSG_PIC_UP:
			G_CurrentSystemDevStatus.ZhuaPaiLine = 1;
			InLineUP();
			break;
		case MSG_PIC_DOWN:
			G_CurrentSystemDevStatus.ZhuaPaiLine = 0;
			InLineDown();
			break;
		case MSG_REMOTECONTROL:
			WorkStation(KeyTran(wParam));
			break;
		case MSG_CLOSE:
			DestroyMainWindow (hWnd);
			PostQuitMessage (hWnd);
			return 0;
		case MSG_CRADENENT:
			if (GetEnableIC())
			{
				SetCardNO(lParam);//必须先赋予卡号
				switch (wParam)
				{
					case  CSC_CARDENTER ://				1201  //卡进入读卡器可读范围
						SetCardExist(T);
						break;
					case CSC_CARDEXIT:
						SetCardExist(F);
						break;
				}
				SetCardInReader(T);
				WorkStation(wParam);
				SetCardInReader(F);
			}
			break;
	}
	return DefaultMainWinProc (hWnd, message, wParam, lParam);
}
Пример #27
0
/*
 *  ======== RcmServerThreadFxn ========
 *     RCM server test thread function
 */
Void RcmServerThreadFxn (Void *arg)
{
    RcmServer_Params    rcmServerParams;
    UInt                fxnIdx;
    Char *              rcmServerName       = RCMSERVER_NAME;
    Int                 status              = 0;

    /* Rcm server module init */
    Osal_printf ("RcmServerThreadFxn: RCM Server module init.\n");
    RcmServer_init ();

    /* Rcm server module params init*/
    Osal_printf ("RcmServerThreadFxn: RCM Server module params init.\n");
    status = RcmServer_Params_init (&rcmServerParams);
    if (status < 0) {
        Osal_printf ("RcmServerThreadFxn: Error in RCM Server instance params "
                        "init \n");
        goto exit;
    }
    Osal_printf ("RcmServerThreadFxn: RCM Server instance params init "
                   "passed \n");

    /* Create the RcmServer instance */
    Osal_printf ("RcmServerThreadFxn: Creating RcmServer instance %s.\n",
        rcmServerName);
    status = RcmServer_create (rcmServerName, &rcmServerParams,
                                &rcmServerHandle);
    if (status < 0) {
        Osal_printf ("RcmServerThreadFxn: Error in RCM Server create.\n");
        goto exit;
    }
    Osal_printf ("RcmServerThreadFxn: RCM Server Create passed \n");

    sem_init (&serverThreadSync, 0, 0);

    /* Register the remote functions */
    Osal_printf ("RcmServerThreadFxn: Registering remote function - "
                "fxnDouble\n");
    status = RcmServer_addSymbol (rcmServerHandle, "fxnDouble", fxnDouble,
                                    &fxnIdx);
    if ((status < 0) || (fxnIdx == 0xFFFFFFFF)) {
        Osal_printf ("RcmServerThreadFxn: Add symbol failed.\n");
        goto exit;
    }

    Osal_printf ("RcmServerThreadFxn: Registering remote function - "
                "fxnExit\n");
    status = RcmServer_addSymbol (rcmServerHandle, "fxnExit", fxnExit, &fxnIdx);
    if ((status < 0) || (fxnIdx == 0xFFFFFFFF)) {
        Osal_printf ("RcmServerThreadFxn: Add symbol failed.\n");
        goto exit;
    }

    Osal_printf ("RcmServerThreadFxn: Start RCM server thread \n");
    RcmServer_start (rcmServerHandle);
    Osal_printf ("RcmServerThreadFxn: RCM Server start passed \n");

    sem_wait (&serverThreadSync);

    sem_post (&mainThreadWait);

exit:
    Osal_printf ("RcmServerThreadFxn: Leaving RCM server test thread "
                    "function \n");
    return;
}
Пример #28
0
Файл: lock.c Проект: Algy/uwsgi
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
	sem_post((sem_t *) uli->lock_ptr);
	uli->pid = 0;
}
Пример #29
0
bool Sem::Post()
{
	return sem_post(&m_sem) == 0;
}
Пример #30
0
static void max11802_worker(FAR void *arg)
{
  FAR struct max11802_dev_s    *priv = (FAR struct max11802_dev_s *)arg;
  FAR struct max11802_config_s *config;
  uint16_t                      x;
  uint16_t                      y;
  uint16_t                      xdiff;
  uint16_t                      ydiff;
  bool                          pendown;
  int                           ret;
  int                           tags, tags2;

  ASSERT(priv != NULL);

  /* Get a pointer the callbacks for convenience (and so the code is not so
   * ugly).
   */

  config = priv->config;
  DEBUGASSERT(config != NULL);

  /* Disable the watchdog timer.  This is safe because it is started only
   * by this function and this function is serialized on the worker thread.
   */

  wd_cancel(priv->wdog);

  /* Lock the SPI bus so that we have exclusive access */

  max11802_lock(priv->spi);

  /* Start coordinate measurement */

  (void)max11802_sendcmd(priv, MAX11802_CMD_MEASUREXY, &tags);

  /* Get exclusive access to the driver data structure */

  do
    {
      ret = sem_wait(&priv->devsem);

      /* This should only fail if the wait was cancelled by an signal
       * (and the worker thread will receive a lot of signals).
       */

      DEBUGASSERT(ret == OK || errno == EINTR);
    }
  while (ret < 0);

  /* Check for pen up or down by reading the PENIRQ GPIO. */

  pendown = config->pendown(config);

  /* Handle the change from pen down to pen up */

  if (pendown)
    {
      iinfo("\nPD\n");
    }
  else
    {
      iinfo("\nPU\n");
    }

  if (!pendown)
    {
      /* The pen is up.. reset thresholding variables. */

      priv->threshx = INVALID_THRESHOLD;
      priv->threshy = INVALID_THRESHOLD;

      /* Ignore the interrupt if the pen was already up (CONTACT_NONE ==
       * pen up and already reported; CONTACT_UP == pen up, but not
       * reported).
       */

      iinfo("\nPC%d\n", priv->sample.contact);

      if (priv->sample.contact == CONTACT_NONE ||
          priv->sample.contact == CONTACT_UP)

        {
          goto ignored;
        }

      /* The pen is up.  NOTE: We know from a previous test, that this is a
       * loss of contact condition.  This will be changed to CONTACT_NONE
       * after the loss of contact is sampled.
       */

       priv->sample.contact = CONTACT_UP;
    }

  /* It is a pen down event.  If the last loss-of-contact event has not been
   * processed yet, then we have to ignore the pen down event (or else it
   * will look like a drag event)
   */

  else if (priv->sample.contact == CONTACT_UP)
    {
      /* If we have not yet processed the last pen up event, then we
       * cannot handle this pen down event. We will have to discard it.
       * That should be okay because we will set the timer to to sample
       * again later.
       */

       iinfo("Previous pen up event still in buffer\n");
       max11802_notify(priv);
       wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,
                (uint32_t)priv);
       goto ignored;
    }
  else
    {
      /* Wait for data ready
       *
       * Note: MAX11802 signals the readiness of the results using
       * the lowest 4 bits of the result. However these are the
       * last bits to be read out of the device. It appears that
       * the hardware value can change in the middle of the readout,
       * causing the upper bits to be still invalid even though lower
       * bits indicate valid result.
       *
       * We work around this by reading the registers once more after
       * the tags indicate they are ready.
       */

      int readycount = 0;
      do
        {
#ifdef CONFIG_MAX11802_SWAPXY
          x = max11802_sendcmd(priv, MAX11802_CMD_YPOSITION, &tags);
          y = max11802_sendcmd(priv, MAX11802_CMD_XPOSITION, &tags2);
#else
          x = max11802_sendcmd(priv, MAX11802_CMD_XPOSITION, &tags);
          y = max11802_sendcmd(priv, MAX11802_CMD_YPOSITION, &tags2);
#endif
          if (tags != 0xF && tags2 != 0xF)
            {
              readycount++;
            }
        }
      while (readycount < 2);

      /* Continue to sample the position while the pen is down */

      wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,
               (uint32_t)priv);

      /* Check if data is valid */

      if ((tags & 0x03) != 0)
        {
          iinfo("Touch ended before measurement\n");
          goto ignored;
        }

      /* Perform a thresholding operation so that the results will be more
       * stable.  If the difference from the last sample is small, then
       * ignore the event.
       *
       * REVISIT:  Should a large change in pressure also generate a event?
       */

      xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x);
      ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y);

      /* Check the thresholds.  Bail if there is no significant difference */

      if (xdiff < CONFIG_MAX11802_THRESHX && ydiff < CONFIG_MAX11802_THRESHY)
        {
          /* Little or no change in either direction ... don't report anything. */

          goto ignored;
        }

      /* When we see a big difference, snap to the new x/y thresholds */

      priv->threshx       = x;
      priv->threshy       = y;

      /* Update the x/y position in the sample data */

      priv->sample.x      = priv->threshx;
      priv->sample.y      = priv->threshy;

      /* The X/Y positional data is now valid */

      priv->sample.valid = true;

      /* If this is the first (acknowledged) pen down report, then report
       * this as the first contact.  If contact == CONTACT_DOWN, it will be
       * set to set to CONTACT_MOVE after the contact is first sampled.
       */

      if (priv->sample.contact != CONTACT_MOVE)
        {
          /* First contact */

          priv->sample.contact = CONTACT_DOWN;
        }
    }

  /* Indicate the availability of new sample data for this ID */

  priv->sample.id = priv->id;
  priv->penchange = true;

  /* Notify any waiters that new MAX11802 data is available */

  max11802_notify(priv);

ignored:
  config->enable(config, true);

  /* Release our lock on the state structure and unlock the SPI bus */

  sem_post(&priv->devsem);
  max11802_unlock(priv->spi);
}