Beispiel #1
0
static void
create_thread (
  plc_sThread	*tp,
  plc_sProctbl	*ptp,
  plc_sProcess	*pp
)
{
  pwr_tStatus	sts;
  long int phase;

  tp->aref.Objid = ptp->thread;
  tp->init = ptp->init;
  tp->exec = ptp->exec;
  tp->first_scan = 1;

  tp->PlcThread = pwrb_PlcThread_Init(&sts, tp);
  tp->csup_lh = csup_Init(&sts, ptp->thread, tp->f_scan_time);

  tp->i_scan_time = tp->f_scan_time * 1000.0 + 0.5;

  time_FloatToD(&tp->scan_time, tp->f_scan_time);

  tp->pp = pp;
 
  plc_inittimer(tp);
  tp->exit = FALSE;
  link_io_copy_areas(tp);

  que_Create(&sts, &tp->q_in);
  que_Create(&sts, &tp->q_out);

  sts = gdh_ObjidToName(ptp->thread, tp->name, sizeof(tp->name), cdh_mNName);
  if (EVEN(sts)) {
    errh_Error("Get name of thread object %s, %m", cdh_ObjidToString(NULL, ptp->thread, 1), sts);
    return;
  }

  sts = gdh_ObjidToPointer(ptp->thread, (void *)&tp->PlcThread);
  if (EVEN(sts)) {
    errh_Error("Direct link to thread object \"%s\", %m", tp->name, sts);
    return;
  }

#if defined OS_LYNX && USE_RT_TIMER
  sem_init(&tp->ScanSem, 0, 0);
  tp->ScanMultiple = tp->i_scan_time / (CLK_TCK/1000);
  tp->IntervalCount = tp->ScanMultiple; 
#endif


  sts = thread_Create(&tp->tid, tp->name, (void *(*)())&plc_thread, tp);
  if (EVEN(sts)) {
    errh_Error("Creating thread \"%s\", %m", tp->name, sts);
    return;
  }

  /* Wait for thread to initialize.  */
  phase = (long int)que_Get(&sts, &tp->q_out, NULL, NULL);
  pwr_Assert(phase == 1);
}
static void *mb_connect( void *arg)
{
  io_sRack *rp = (io_sRack *)arg;
  io_sServerLocal* local = rp->Local;
  int sts;
  pwr_sClass_Modbus_TCP_Server *op;
  struct sockaddr_in r_addr;
  socklen_t r_addr_len;
  int c_socket;
  mb_sCondata *condata;
  int idx;
  int found;
  int i;
  
  op = (pwr_sClass_Modbus_TCP_Server *) rp->op;


  while ( 1) {
    /* Wait for client connect request */
    r_addr_len = sizeof(r_addr);

    c_socket = accept( local->s, (struct sockaddr *) &r_addr, &r_addr_len);
    if ( c_socket < 0) {
      errh_Error( "Error accept IO modbus tcp server %s, %d", rp->Name, local->s);
      continue;
    }
    if ( op->DisableServer)
      continue;

    errh_Info( "Connection accepted for IO modbus tcp server %s, %d", rp->Name, c_socket);

    /* Close other connections to this address */
    for ( i = 0; i < MB_MAX_CONNECTIONS; i++) {
      if ( local->connections[i].occupied && 
	   r_addr_len == local->connections[i].addrlen &&
	   r_addr.sin_family == local->connections[i].addr.sin_family &&
	   memcmp( &r_addr.sin_addr, &local->connections[i].addr.sin_addr, sizeof(r_addr.sin_addr)) == 0) {
	mb_close_connection( rp, i);
      }
    }
    

    /* Find next empty in connection list */
    found = 0;
    for ( i = 0; i < MB_MAX_CONNECTIONS; i++) {
      if ( !local->connections[i].occupied) {
	found = 1;
	idx = i;
	break;
      }
    }

    if ( !found) {
      /* Remove the oldest connection */
      int oldest_idx = 0;

      for ( i = 1; i < MB_MAX_CONNECTIONS; i++) {
	if ( time_Acomp( &local->connections[i].last_req_time, &local->connections[oldest_idx].last_req_time) < 0)
	  oldest_idx = i;
      }
      mb_close_connection( rp, oldest_idx);
      errh_Info( "Connection closed, IO modbus tcp server %s, %d", rp->Name, local->s);
      idx = oldest_idx;
    }

    local->connections[idx].c_socket = c_socket;
    local->connections[idx].occupied = 1;
    time_GetTime( &local->connections[idx].last_req_time);
    local->connections[idx].addrlen = r_addr_len;
    memcpy( &local->connections[idx].addr, &r_addr, r_addr_len);

    /* Create a thread for this connection */
    condata = (mb_sCondata *) malloc( sizeof(mb_sCondata));
    condata->rp = rp;
    condata->idx = idx;
    

    sts = thread_Create( &local->connections[idx].t, 0, mb_receive, (void *)condata);
    if ( EVEN(sts)) {
      local->connections[idx].occupied = 0;
      errh_Error( "Error creating thread IO modbus tcp server %s, %d", rp->Name, local->s);
      free( condata);
      continue;
    }
  }
  return 0;
}