⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 download.c

📁 chord 源码 http://pdos.csail.mit.edu/chord/
💻 C
字号:
#include <chord.h>#include <location.h>#include <locationtable.h>#include <dhash_common.h>#include <dhash.h>#include <misc_utils.h>#include "dhblock.h"#include "download.h"// ---------------------------------------------------------------------------// dhash_download -- downloads a block of a specific chord node.  That node//                   should already be in the location table.dhash_download::dhash_download (ptr<vnode> clntnode, ptr<dhash> dh, 				chord_node source,				blockID blockID, cbretrieve_t cb,				cbtmo_t cb_tmo) :  error (false),  source (source),  blckID (blockID),  cb (cb),  buffer (NULL),  buf_len (0),  dh (dh),  bytes_read (0),  fetch_acked (false),  called_cb (false) {  assert (dh);  ptr<s_dhash_fetch_arg> arg = New refcounted<s_dhash_fetch_arg>;  arg->key   = blckID.ID;  arg->ctype = blckID.ctype;  ptr<dhash_fetchiter_res> res = New refcounted<dhash_fetchiter_res> ();    arg->nonce = dh->register_fetch_callback (wrap (this, 						  &dhash_download::gotchunk));  nonce = arg->nonce;  clntnode->doRPC     (source, dhash_program_1, DHASHPROC_FETCHITER, arg, res,      wrap (this, &dhash_download::sent_request, res), cb_tmo);    }dhash_download::~dhash_download (){  if (buffer) {    free (buffer);    buffer = NULL;  }    dh->unregister_fetch_callback (nonce);}voiddhash_download::sent_request (ptr<dhash_fetchiter_res> res, clnt_stat err){  assert (!fetch_acked);  fetch_acked = true;  if (err) {    strbuf e;    e << "RPC error, status " << err;    fail ((str) e);   } else if (res && res->status != DHASH_INPROGRESS) {    strbuf e;    e << "bad status, status " << res->status;    fail ((str) e);  } else    ;  // don't call check_finish before gotchunk has finished, unless gotchunk  // will never be called.  otherwise you'll have issues with  // buf_len == bytes_read == 0  if (called_cb || error) {    check_finish ();  }}  void dhash_download::gotchunk (str data, int offset, int totsz){  //first chunk  if (offset < 0) {    fail ("Block not found");  } else {    if (buf_len == 0) {      buf_len = totsz;      buffer = (char *)malloc (buf_len);    }    add_data (data, offset);  }    check_finish ();}void dhash_download::add_data (str sdata, int off){  int len = sdata.len ();  const char *data = sdata.cstr ();  if ((unsigned)(off + len) > (u_int)buf_len)    fail (strbuf ("bad chunk: off %d, len %d, block %ld", 		  off, len, buf_len));  else {    memcpy (buffer + off, data, len);    bytes_read += len;  }}voiddhash_download::check_finish (){  //XXX new finish condition  if (bytes_read == buf_len || error) {     ptr<dhash_block> block = NULL;    /* got all chunks */    if (!error)  {      block = New refcounted<dhash_block> (buffer, buf_len, blckID.ctype);      block->source = source.x;      block->hops   = 0;      block->errors = 0;    }    if (!called_cb) {      (*cb) (block);      called_cb = true;    }    // If the fetch has been acked (sent_request has been called), then we're    // good to delete, because either (a) gotchunk has not been called yet,    // and sent_request got an error, so it never will get called, or     // (b) gotchunk was called and is either finished or gave an error,    // in either case we're done (otherwise we wouldn't be in this block)    if( fetch_acked ) {      delete this;    }  }}voiddhash_download::fail (str errstr){  warn << "dhash_download failed: " << blckID << ": "       << errstr << " at " << source << "\n";  error = true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -