Пример #1
0
void app_XBmod_Numtask( void*arg )
{
	uint8_t key_buf;
	uint8_t id;
	_GR_CURpage = 0;
	id= os_task_assign_stk_build( _display_task,10);
	os_sem_creat(&_sem,1);
	msleep(APP_100_MS);
	while(1)
	{
		msleep(TYPE_DELAY);
		if ( os_task_delete_req( SELF_PRO ) == OS_TASK_DEL_REQ )
		{
			OS_DELETE_REQ( id );
		    app_XBmod_window_destory();
			os_task_delete( SELF_PRO );   			
		}
		if ( GUI_key_read(m_XBmod_win_Obj,&key_buf, 1 ) == 1 ) 
		{
			if(key_buf==KEY_RIGHT)
			{
			    _GR_CURpage = (_GR_CURpage==2)?(0):(_GR_CURpage+1);
 				os_sem_post(_sem);
			}	
			else if(key_buf==KEY_LEFT)
			{
			    _GR_CURpage = (_GR_CURpage==0)?(2):(_GR_CURpage-1);
 				os_sem_post(_sem);
			}	
		}
	}
}
Пример #2
0
int log_puts(LOG_HANDLE ctx, int level, const char* msg, unsigned int msglen)
{
	if(msglen==0) msglen = (unsigned int)strlen(msg);
	if(ctx->stream.buf==NULL) return map[ctx->type].func_write(ctx, level, msg, msglen);

	for(;;) {
		os_mutex_lock(&ctx->stream.mtx);
		if(ctx->stream.len+sizeof(msglen)+msglen <= ctx->stream.max) break;
		ctx->stream.ouque_size++;
		os_mutex_unlock(&ctx->stream.mtx);
		os_sem_wait(&ctx->stream.ouque);
	}

	stream_write(ctx, (char*)&msglen, (unsigned int)sizeof(msglen));
	stream_write(ctx, msg, msglen);
	ctx->stream.inque_size++;

	if(ctx->stream.ouque_size>0) {
		ctx->stream.ouque_size--;
		os_sem_post(&ctx->stream.ouque);
	}

	os_sem_post(&ctx->stream.inque);
	os_mutex_unlock(&ctx->stream.mtx);

	get_level_string(level);

	return ERR_NOERROR;
}
Пример #3
0
void
set_thread_state(struct thread *thread, lispobj state)
{
    int i, waitcount = 0;
    sigset_t old;
    block_blockable_signals(&old);
    os_sem_wait(thread->state_sem, "set_thread_state");
    if (thread->state != state) {
        if ((STATE_STOPPED==state) ||
            (STATE_DEAD==state)) {
            waitcount = thread->state_not_running_waitcount;
            thread->state_not_running_waitcount = 0;
            for (i=0; i<waitcount; i++)
                os_sem_post(thread->state_not_running_sem, "set_thread_state (not running)");
        }
        if ((STATE_RUNNING==state) ||
            (STATE_DEAD==state)) {
            waitcount = thread->state_not_stopped_waitcount;
            thread->state_not_stopped_waitcount = 0;
            for (i=0; i<waitcount; i++)
                os_sem_post(thread->state_not_stopped_sem, "set_thread_state (not stopped)");
        }
        thread->state = state;
    }
    os_sem_post(thread->state_sem, "set_thread_state");
    thread_sigmask(SIG_SETMASK, &old, NULL);
}
Пример #4
0
static inline bool queue_frame(struct obs_core_video *video, bool raw_active,
		struct obs_vframe_info *vframe_info, int prev_texture)
{
	bool duplicate = !video->gpu_encoder_avail_queue.size ||
		(video->gpu_encoder_queue.size && vframe_info->count > 1);

	if (duplicate) {
		struct obs_tex_frame *tf = circlebuf_data(
				&video->gpu_encoder_queue,
				video->gpu_encoder_queue.size - sizeof(*tf));

		/* texture-based encoding is stopping */
		if (!tf) {
			return false;
		}

		tf->count++;
		os_sem_post(video->gpu_encode_semaphore);
		goto finish;
	}

	struct obs_tex_frame tf;
	circlebuf_pop_front(&video->gpu_encoder_avail_queue, &tf, sizeof(tf));

	if (tf.released) {
		gs_texture_acquire_sync(tf.tex, tf.lock_key, GS_WAIT_INFINITE);
		tf.released = false;
	}

	/* the vframe_info->count > 1 case causing a copy can only happen if by
	 * some chance the very first frame has to be duplicated for whatever
	 * reason.  otherwise, it goes to the 'duplicate' case above, which
	 * will ensure better performance. */
	if (raw_active || vframe_info->count > 1) {
		gs_copy_texture(tf.tex, video->convert_textures[prev_texture]);
	} else {
		gs_texture_t *tex = video->convert_textures[prev_texture];
		gs_texture_t *tex_uv = video->convert_uv_textures[prev_texture];

		video->convert_textures[prev_texture] = tf.tex;
		video->convert_uv_textures[prev_texture] = tf.tex_uv;

		tf.tex = tex;
		tf.tex_uv = tex_uv;
		tf.handle = gs_texture_get_shared_handle(tex);
	}

	tf.count = 1;
	tf.timestamp = vframe_info->timestamp;
	tf.released = true;
	gs_texture_release_sync(tf.tex, ++tf.lock_key);
	circlebuf_push_back(&video->gpu_encoder_queue, &tf, sizeof(tf));

	os_sem_post(video->gpu_encode_semaphore);

finish:
	return --vframe_info->count;
}
Пример #5
0
unsigned int ZION_CALLBACK log_thread(void* arg)
{
	LOG_CTX* ctx = (LOG_CTX*)arg;
	unsigned int msglen = ctx->stream.len;
	char buf[1000];
	int level = 0;

	for(;;) {
		os_sem_wait(&ctx->stream.inque);

		os_mutex_lock(&ctx->stream.mtx);
		if(ctx->stream.inque_size==0) { os_mutex_unlock(&ctx->stream.mtx); break; }

		stream_read(ctx, (char*)&msglen, (unsigned int)sizeof(msglen));
		stream_read(ctx, buf, msglen);
		buf[msglen] = '\0';

		if(ctx->stream.ouque_size>0) {
			ctx->stream.ouque_size--;
			os_sem_post(&ctx->stream.ouque);
		}

		ctx->stream.inque_size--;
		os_mutex_unlock(&ctx->stream.mtx);

		map[ctx->type].func_write(ctx, level, buf, msglen);
	}
	return 0;
}
Пример #6
0
void
wait_for_thread_state_change(struct thread *thread, lispobj state)
{
    sigset_t old;
    os_sem_t *wait_sem;
    block_blockable_signals(&old);
  start:
    os_sem_wait(thread->state_sem, "wait_for_thread_state_change");
    if (thread->state == state) {
        switch (state) {
        case STATE_RUNNING:
            wait_sem = thread->state_not_running_sem;
            thread->state_not_running_waitcount++;
            break;
        case STATE_STOPPED:
            wait_sem = thread->state_not_stopped_sem;
            thread->state_not_stopped_waitcount++;
            break;
        default:
            lose("Invalid state in wait_for_thread_state_change: "OBJ_FMTX"\n", state);
        }
    } else {
        wait_sem = NULL;
    }
    os_sem_post(thread->state_sem, "wait_for_thread_state_change");
    if (wait_sem) {
        os_sem_wait(wait_sem, "wait_for_thread_state_change");
        goto start;
    }
    thread_sigmask(SIG_SETMASK, &old, NULL);
}
Пример #7
0
static void rtmp_stream_destroy(void *data)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream) && !connecting(stream)) {
		pthread_join(stream->send_thread, NULL);

	} else if (connecting(stream) || active(stream)) {
		if (stream->connecting)
			pthread_join(stream->connect_thread, NULL);

		os_event_signal(stream->stop_event);

		if (active(stream)) {
			os_sem_post(stream->send_sem);
			obs_output_end_data_capture(stream->output);
			pthread_join(stream->send_thread, NULL);
		}
	}

	if (stream) {
		free_packets(stream);
		dstr_free(&stream->path);
		dstr_free(&stream->key);
		dstr_free(&stream->username);
		dstr_free(&stream->password);
		dstr_free(&stream->encoder_name);
		os_event_destroy(stream->stop_event);
		os_sem_destroy(stream->send_sem);
		pthread_mutex_destroy(&stream->packets_mutex);
		circlebuf_free(&stream->packets);
		bfree(stream);
	}
}
Пример #8
0
static void rtmp_stream_data(void *data, struct encoder_packet *packet)
{
	struct rtmp_stream    *stream = data;
	struct encoder_packet new_packet;
	bool                  added_packet = false;

	if (disconnected(stream))
		return;

	if (packet->type == OBS_ENCODER_VIDEO)
		obs_parse_avc_packet(&new_packet, packet);
	else
		obs_duplicate_encoder_packet(&new_packet, packet);

	pthread_mutex_lock(&stream->packets_mutex);

	if (!disconnected(stream)) {
		added_packet = (packet->type == OBS_ENCODER_VIDEO) ?
			add_video_packet(stream, &new_packet) :
			add_packet(stream, &new_packet);
	}

	pthread_mutex_unlock(&stream->packets_mutex);

	if (added_packet)
		os_sem_post(stream->send_sem);
	else
		obs_free_encoder_packet(&new_packet);
}
Пример #9
0
void video_output_unlock_frame(video_t *video)
{
	if (!video) return;

	pthread_mutex_lock(&video->data_mutex);

	video->available_frames--;
	os_sem_post(video->update_semaphore);

	pthread_mutex_unlock(&video->data_mutex);
}
Пример #10
0
void mp_media_stop(mp_media_t *m)
{
	pthread_mutex_lock(&m->mutex);
	if (m->active) {
		m->reset = true;
		m->active = false;
		m->stopping = true;
		os_sem_post(m->sem);
	}
	pthread_mutex_unlock(&m->mutex);
}
Пример #11
0
static void mp_kill_thread(mp_media_t *m)
{
	if (m->thread_valid) {
		pthread_mutex_lock(&m->mutex);
		m->kill = true;
		pthread_mutex_unlock(&m->mutex);
		os_sem_post(m->sem);

		pthread_join(m->thread, NULL);
	}
}
Пример #12
0
/********************************************************************
 * @创建人:揭成
 * @功能 : 设置蜂鸣响应,向蜂鸣任务发送信号量
 *
 * @输入 :NONE
 *
 *@输出  :NONE
********************************************************************/
void app_global_buz_response( Bsize_t response_jiffies )
{
	if ( m_buz_task_pro == INVALID_PRO )
		return ;
	os_lock( m_buz_lock );
	m_buz_ctl_buf.alarm_time = response_jiffies;
	m_buz_ctl_buf.ctl_times = 1;
	m_buz_ctl_buf.stop_time = 0;
	os_unlock( m_buz_lock );
	os_sem_post( m_buz_sem );
	return;
}
Пример #13
0
/* Only access thread state with blockables blocked. */
lispobj
thread_state(struct thread *thread)
{
    lispobj state;
    sigset_t old;
    block_blockable_signals(&old);
    os_sem_wait(thread->state_sem, "thread_state");
    state = thread->state;
    os_sem_post(thread->state_sem, "thread_state");
    thread_sigmask(SIG_SETMASK, &old, NULL);
    return state;
}
Пример #14
0
/********************************************************************
 * @创建人:揭成
 * @功能 : 设置蜂鸣报警,向蜂鸣任务发送信号量
 *
 * @输入 :NONE
 *
 *@输出  :NONE
********************************************************************/
void app_global_buz_alarm( Bsize_t stop_jiffies, Bsize_t alarm_jiffies, Bsize_t cycle_times )
{
	if ( m_buz_task_pro == INVALID_PRO )
		return ;
	os_lock( m_buz_lock );
	m_buz_ctl_buf.alarm_time = alarm_jiffies;
	m_buz_ctl_buf.ctl_times  = cycle_times;
	m_buz_ctl_buf.stop_time  = stop_jiffies;
	os_unlock( m_buz_lock );
	os_sem_post( m_buz_sem );
	return;
}
Пример #15
0
static void wq_wake(wq_t *wq)
{
    os_thread_mutex_lock(&wq->lock);
    if (wq->wait != 0)
    {
        os_sem_post(&wq->sem);
        wq->wait = 0;
    }
    else
        wq->ev = 1;

    os_thread_mutex_unlock(&wq->lock);
}
Пример #16
0
void video_output_stop(video_t *video)
{
	void *thread_ret;

	if (!video)
		return;

	if (video->initialized) {
		video->initialized = false;
		video->stop = true;
		os_sem_post(video->update_semaphore);
		pthread_join(video->thread, &thread_ret);
	}
}
Пример #17
0
void mp_media_play(mp_media_t *m, bool loop)
{
	pthread_mutex_lock(&m->mutex);

	if (m->active)
		m->reset = true;

	m->looping = loop;
	m->active = true;

	pthread_mutex_unlock(&m->mutex);

	os_sem_post(m->sem);
}
Пример #18
0
/********************************************************************
 * @创建人 :揭成
 * @功能 :WAVE模块主任务
 * @输入 :NONE
 *@输出  :NONE
********************************************************************/
void app_XBmod_GRtask( void*arg )
{
	uint8_t key_buf;
	uint8_t id;
	_GR_CURpage = 0;
	os_sem_creat(&_GR_sem,1);
	id= os_task_assign_stk_build( _GRdisplay_task,10);
	msleep(APP_100_MS);
	while(1)
	{
		msleep(TYPE_DELAY);
		if ( os_task_delete_req( SELF_PRO ) == OS_TASK_DEL_REQ )
		{
			OS_DELETE_REQ( id );
		    app_XBmod_window_destory();
			os_task_delete( SELF_PRO );   			
		}
		if ( GUI_key_read(m_XBmod_win_Obj,&key_buf, 1 ) == 1 ) 
		{
			if(key_buf==KEY_RIGHT)
			{
			    _GR_CURpage = (_GR_CURpage==2)?(0):(_GR_CURpage+1);
 				os_sem_post(_GR_sem);
			}	
			else if(key_buf==KEY_LEFT)
			{
			    _GR_CURpage = (_GR_CURpage==0)?(2):(_GR_CURpage-1);
 				os_sem_post(_GR_sem);
			}	
			else if(key_buf==KEY_F1)
			{
				GUI_radio_select(_phaseR,0);
				_GR_CURpage = 0;
				os_sem_post(_GR_sem);
			}
			else if(key_buf==KEY_F2)
			{
				GUI_radio_select(_phaseR,1);
				_GR_CURpage = 0;
				os_sem_post(_GR_sem);
			}
			else if(key_buf==KEY_F3)
			{
				GUI_radio_select(_phaseR,2);
				_GR_CURpage = 0;
				os_sem_post(_GR_sem);
			}			
			else if(key_buf==KEY_F4)
			{
				GUI_checkbox_state_modify(GUI_Getchild(GUI_KEY_SELECT_WAY,GET_DOBJ(2)));
				os_sem_post(_GR_sem);
			}
		}
	}
}
Пример #19
0
static void rtmp_stream_stop(void *data)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream))
		return;

	if (connecting(stream))
		pthread_join(stream->connect_thread, NULL);

	os_event_signal(stream->stop_event);

	if (active(stream)) {
		os_sem_post(stream->send_sem);
		obs_output_end_data_capture(stream->output);
	}
}
Пример #20
0
static void rtmp_stream_destroy(void *data)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream) && !connecting(stream)) {
		pthread_join(stream->send_thread, NULL);

	} else if (connecting(stream) || active(stream)) {
		if (stream->connecting)
			pthread_join(stream->connect_thread, NULL);

		stream->stop_ts = 0;
		os_event_signal(stream->stop_event);

		if (active(stream)) {
			os_sem_post(stream->send_sem);
			obs_output_end_data_capture(stream->output);
			pthread_join(stream->send_thread, NULL);
		}
	}

	free_packets(stream);
	dstr_free(&stream->path);
	dstr_free(&stream->key);
	dstr_free(&stream->username);
	dstr_free(&stream->password);
	dstr_free(&stream->encoder_name);
	dstr_free(&stream->bind_ip);
	os_event_destroy(stream->stop_event);
	os_sem_destroy(stream->send_sem);
	pthread_mutex_destroy(&stream->packets_mutex);
	circlebuf_free(&stream->packets);
#ifdef TEST_FRAMEDROPS
	circlebuf_free(&stream->droptest_info);
#endif

	os_event_destroy(stream->buffer_space_available_event);
	os_event_destroy(stream->buffer_has_data_event);
	os_event_destroy(stream->socket_available_event);
	os_event_destroy(stream->send_thread_signaled_exit);
	pthread_mutex_destroy(&stream->write_buf_mutex);

	if (stream->write_buf)
		bfree(stream->write_buf);
	bfree(stream);
}
Пример #21
0
int log_close(LOG_HANDLE ctx)
{
	int ret;

	if(ctx->stream.buf!=NULL) {
		os_sem_post(&ctx->stream.inque);
		os_thread_wait(ctx->stream.thread, NULL);

		os_sem_destroy(&ctx->stream.inque);
		os_sem_destroy(&ctx->stream.ouque);
		os_mutex_destroy(&ctx->stream.mtx);
	}

	ret = map[ctx->type].func_close(ctx);
	free(ctx);
	return ret;
}
Пример #22
0
static void rtmp_stream_stop(void *data, uint64_t ts)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream))
		return;

	if (connecting(stream))
		pthread_join(stream->connect_thread, NULL);

	stream->stop_ts = ts / 1000ULL;
	os_event_signal(stream->stop_event);

	if (active(stream)) {
		if (stream->stop_ts == 0)
			os_sem_post(stream->send_sem);
	}
}
Пример #23
0
static void rtmp_stream_stop(void *data)
{
	struct rtmp_stream *stream = data;
	void *ret;

	os_event_signal(stream->stop_event);

	if (stream->connecting)
		pthread_join(stream->connect_thread, &ret);

	if (stream->active) {
		obs_output_end_data_capture(stream->output);
		os_sem_post(stream->send_sem);
		pthread_join(stream->send_thread, &ret);
		RTMP_Close(&stream->rtmp);
	}

	os_event_reset(stream->stop_event);

	stream->sent_headers = false;
}
Пример #24
0
static int submit_req(device_t *disk_device, header_t **_req)
{
  header_t *req = *_req;

  if (req->type == NBD_HEADER_LOCK)
  {
      td_merge_lock(disk_device, req);

      __wait_for_all_completion(disk_device);

      nbd_list_post(&nbd_server.list_root.free, req, -1);
      *_req = NULL;
      os_sem_post(&disk_device->lock_sem_disk);
      return RDEV_REQUEST_NONE_ENDED;
  }

  if (req->io.desc.sector_nb == 0) /* Is a flush */
  {
      EXA_ASSERT(req->io.desc.request_type == NBD_REQ_TYPE_WRITE);
      __wait_for_all_completion(disk_device);
      /* Once the flush is called, we wait for all pending IO to
       * finish. Upon return we have the guaranty that every
       * pending operation on disk is finished and drive is
       * flushed. */
      exa_rdev_flush(disk_device->handle);
      req->io.desc.result = 0;
      return RDEV_REQUEST_END_OK;
  }

  if (!req->io.desc.bypass_lock && td_is_locked(disk_device, req))
  {
      /* Being here means that the IO cannot be done because of locks, thus
       * we send back a EAGAIN to caller to tell that the IO must be
       * re-submitted later. */
      req->io.desc.result = -EAGAIN;
      return RDEV_REQUEST_END_OK;
  }

  return exa_td_process_one_request(_req, disk_device);
}
Пример #25
0
static os_result
os_procWrapper(
    os_procContextData process_procContextData,
    char *executable_file,
    os_int32 *startRoutine,
    const char *arguments,
    TASK_ID parent,
    os_sem_t *blockParent)
{
    int taskid;
    os_int32 status = os_resultSuccess;
    os_int32 routine_status = -1;
    os_int32 (*this_startRoutine)(const char *);

#if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR > 8 )
      envPrivateCreate(taskIdSelf(), parent);
      os_sem_post(blockParent);
#endif

    taskid = taskIdSelf();
    os_procSetTaskId(process_procContextData, taskid);
    /* create & set context variable for the task */
    status = os_procAddTaskVar(taskid, executable_file, process_procContextData, 0);
    if (status == os_resultSuccess) {
        status = os_threadNew(process_procContextData->procName);
    }
    if (status == os_resultSuccess) {
        this_startRoutine = (os_int32 *)startRoutine;
        routine_status = this_startRoutine(arguments);
        os_procLocalExit(OS_EXIT_SUCCESS);
        os_threadDeleteTaskVar(taskid, os_threadIdSelf());
        os_procDeleteTaskVar(taskid, executable_file, process_procContextData);
        os_procSetExitValue(process_procContextData, routine_status);
    }

#if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR > 6 && _WRS_VXWORKS_MINOR > 8 )
      envPrivateDestroy(taskIdSelf());
#endif
    return (status);
}
Пример #26
0
static void rtmp_stream_stop(void *data, uint64_t ts)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream) && ts != 0)
		return;

	if (connecting(stream))
		pthread_join(stream->connect_thread, NULL);

	stream->stop_ts = ts / 1000ULL;
	os_event_signal(stream->stop_event);

	if (ts)
		stream->shutdown_timeout_ts = ts +
			(uint64_t)stream->max_shutdown_time_sec * 1000000000ULL;

	if (active(stream)) {
		if (stream->stop_ts == 0)
			os_sem_post(stream->send_sem);
	}
}
Пример #27
0
void rebuild_helper_thread(void *p)
{
  ExamsgHandle mh;
  int err;

  exalog_as(EXAMSG_NBD_SERVER_ID);

  /* initialize examsg framework */
  mh = examsgInit(EXAMSG_NBD_LOCKING_ID);
  EXA_ASSERT(mh != NULL);

  err = examsgAddMbox(mh, EXAMSG_NBD_LOCKING_ID, 1, 5 * EXAMSG_MSG_MAX);
  EXA_ASSERT(err == 0);

  os_sem_post(&nbd_server.mailbox_sem);

  while (nbd_server.run)
  {
      device_t *device;
      ExamsgNbdLock nbd_lock_msg;
      ExamsgMID from;
      struct timeval timeout = { .tv_sec = 0, .tv_usec = 100000 };
      exa_nodeset_t dest_nodes;

      err = examsgWaitTimeout(mh, &timeout);
      /* Just in order to check stopping the thread is required*/
      if (err == -ETIME)
	  continue;

      if (err != 0)
      {
          exalog_error("Locking thread encountered error %s (%d) while "
                       "waiting in event loop.", exa_error_msg(err), err);
          continue;
      }

      err = examsgRecv(mh, &from, &nbd_lock_msg, sizeof(nbd_lock_msg));

      /* No message */
      if (err == 0)
	continue;

      if (err < 0)
      {
          exalog_error("Locking thread encountered error %s (%d) while "
                       "receiving a messsage.", exa_error_msg(err), err);
	  continue;
      }

      switch(nbd_lock_msg.any.type)
      {
      case EXAMSG_NBD_LOCK:
	  /* find device from name */
          /* FIXME devices lock is not held... it should */
          device = find_device_from_uuid(&nbd_lock_msg.disk_uuid);
	  if (device == NULL)
          {
              exalog_error("Unknown device with UUID " UUID_FMT, UUID_VAL(&nbd_lock_msg.disk_uuid));
              err = -CMD_EXP_ERR_UNKNOWN_DEVICE;
              break;
          }
          if (nbd_lock_msg.lock)
          {
              err = exa_disk_lock_zone(device, nbd_lock_msg.locked_zone_start,
                                          nbd_lock_msg.locked_zone_size);
              EXA_ASSERT_VERBOSE(err == 0, "Trying to lock too many zone "
                                 "(>%d). Last zone not succesfully locked "
                                 "(start = %" PRId64 ", size = %" PRId64 " ) "
                                 "on device UUID " UUID_FMT, NBMAX_DISK_LOCKED_ZONES,
                                 nbd_lock_msg.locked_zone_start,
                                 nbd_lock_msg.locked_zone_size,
                                 UUID_VAL(&nbd_lock_msg.disk_uuid));
          }
          else
          {
              err = exa_disk_unlock_zone(device, nbd_lock_msg.locked_zone_start,
                                            nbd_lock_msg.locked_zone_size);
              EXA_ASSERT_VERBOSE(err == 0, "Trying to unlock a never locked "
                                 "zone (unlocked zone start =%" PRId64 ", "
                                 "unlocked zone size = %" PRId64 ") on device"
                                 " UUID " UUID_FMT,
                                 nbd_lock_msg.locked_zone_start,
                                 nbd_lock_msg.locked_zone_size,
                                 UUID_VAL(&nbd_lock_msg.disk_uuid));
          }
	  break;

	default:
	  /* error */
	  EXA_ASSERT_VERBOSE(false, "Locking thread got unknown message of"
                             " type %d ", nbd_lock_msg.any.type);
	  break;
	}

      exa_nodeset_single(&dest_nodes, from.netid.node);
      examsgAckReply(mh, (Examsg *)&nbd_lock_msg, err, from.id, &dest_nodes);
    }

  examsgDelMbox(mh, EXAMSG_NBD_LOCKING_ID);
  examsgExit(mh);
}

/** get the number of sector of the device
 * \param device_path the device to get the number of sector
 * \param nb_sectors64 the number of sectors of the device
 * \return nb_sectors the returned number of sector
 */

static int get_nb_sectors(const char *device_path, uint64_t *nb_sectors)
{
  uint64_t device_size; /* in bytes */
  int retval;
  int fd;

  /* We need the read access to get the size. */
  if ((fd = os_disk_open_raw(device_path, OS_DISK_READ)) < 0)
  {
    exalog_error("cannot open device '%s'  error=%s ",
                 device_path, exa_error_msg(-fd));
    return -CMD_EXP_ERR_OPEN_DEVICE;
  }

  retval = os_disk_get_size(fd, &device_size);
  if (retval < 0)
  {
    exalog_error("os_disk_get_size() error=%s", exa_error_msg(retval));
    if (close(fd) != 0)
      exalog_error("can't EVEN close dev '%s'", device_path);
    return -EXA_ERR_IOCTL;
  }

  retval = close(fd);
  if (retval < 0)
  {
    retval = -errno;
    exalog_error("cannot close device '%s' error=%s ",
                 device_path, exa_error_msg(retval));
    return -CMD_EXP_ERR_CLOSE_DEVICE;
  }

  *nb_sectors = device_size / SECTOR_SIZE;

  /* remove the size of the reserved area for storing admind info */
  *nb_sectors -= RDEV_RESERVED_AREA_IN_SECTORS;

  /* Align the size on 1K
   * this is the best we can do to have the same size of devices on 2.4 and 2.6 kernels due to
   * the fact that kernel 2.4 rounds the size of devices with 1 K
   */
  *nb_sectors -= *nb_sectors % (1024 / SECTOR_SIZE);

  return EXA_SUCCESS;
}