Value not being returned properly?

Jason McLaughlin jasonmc@safesquid.com
Tue Feb 8 23:21:00 GMT 2005


HI,


I'm encountering a problem with some C++ code I'm writing.
I have a function which returns an integer that's not making it's way to the caller... the return value always ends up being 0.

Here's the two methods in question (I removed code not pertinent to the problem, since it's quite long)

----------------------

nt Socket::Read(char *buf, int len, int timeout)
{
 int maxread, pos = 0, x = -1;
 char b[BLOCKSIZE];
 struct pollfd pfd;

 if (timeout != -1 && (len == -1 || inbuf_len < len)) {
  pfd.fd = fd;
  pfd.events = POLLIN;

  x = p_poll(&pfd, 1, timeout * 1000);
  if (x != 1 || pfd.revents & (POLLHUP | POLLERR))
   return -1;
 }

 if (inbuf_len != 0 && len != -1) {
  memcpy(buf, inbuf, (inbuf_len < len) ? inbuf_len : len);
  if (inbuf_len <= len) {
   /* all buffered data used up, clear it */
   pos = inbuf_len;

   Clear(INBUF);

   /* buffer is exact size of requested read size, no need to do any network IO */
   if (pos == len) {
    if (CallBackEvent(READEVENT, len, buf) == -1)
     return -1;

    return len;
   }
  } else {
   /* buffer larger than requested read size, no need to do any network IO */
   /* chop off used part of buffer */
   memmove(inbuf, inbuf + len, inbuf_len - len);
   Resize(inbuf_len - len, INBUF);

   if (CallBackEvent(READEVENT, len, buf) == -1)
    return -1;

   return len;
  }
 }

 maxread = Throttle(IN);


^- right here, maxread is 0



 if (maxread == 0 || maxread > sizeof(b)) 
  maxread = sizeof(b);

}

--------------------

int Socket::Throttle(int which) {
 unsigned int ret = 0;
 long sliceposition;
 struct timeval tv;
 LimitGroup *limitgroup;


 if (which == IN)
  limitgroup = ingroup;
 else
  limitgroup = outgroup;

 if (limitgroup == NULL) return 0;

 limitgroup->Lock();

 if (limitgroup->slicesize == 0) {
  /* new timeslice */
  gettimeofday(&limitgroup->slicestart, NULL);

  limitgroup->Unlock();

  putlog(MMLOG_LIMITS, "returning %d", limitgroup->slicemax);

  return limitgroup->slicemax;
 }

 gettimeofday(&tv, NULL);

 sliceposition = timeval_diff_ms(&limitgroup->slicestart, &tv);

 if (sliceposition >= THROTTLE_TIMESLICE) {
  /* we've gone over the timeslice without using our quota, start a new one. */
  limitgroup->slicesize = 0;

  limitgroup->slicestart = tv;

  limitgroup->Unlock();
  sched_yield();

  putlog(MMLOG_LIMITS, "returning %d", limitgroup->slicemax);

  return limitgroup->slicemax;
 }

 if (limitgroup->slicesize >= limitgroup->slicemax) {
  unsigned int sleeptime = THROTTLE_TIMESLICE - sliceposition;

  /* timeslice quota used up, sleep until the next timeslice. */
  /* holding the lock thru this is fine... it simply prevents the alternative of having
     every thread call usleep */
  usleep(sleeptime * 1000);

  /* yeah I could add the time slept onto tv instead, but this is easier and more accurate since
     usleep can sleep longer due to scheduling anomalies or timer granularity. */
  limitgroup->slicesize = 0;

  gettimeofday(&limitgroup->slicestart, NULL);

  limitgroup->Unlock();
  sched_yield();

  putlog(MMLOG_LIMITS, "returning %d", limitgroup->slicemax);

  return limitgroup->slicemax;
 }

 ret = limitgroup->slicemax - limitgroup->slicesize;

 limitgroup->Unlock();

 putlog(MMLOG_LIMITS, "returning %d", ret);

 return ret;
} 

----------------------------------



What I get is a log message saying "returning 10240", but the maxread variable in Socket::Read is always 0.

I've stepped through it with a debugger and see the same problem... I used valgrind to see if anything funny was happening to the stack
and it showed no problems.

Any ideas, or any other information I can provide that might be useful?


-- 
Oh drat these computers, they're so naughty and so complex - I could pinch them!
- Marvin the Martian



More information about the Gcc-help mailing list