void glxx_buffer_subdata(GLXX_BUFFER_T *buffer, int32_t offset, int32_t size, const void *data) { vcos_assert(offset >= 0 && size >= 0); vcos_assert(data); //if write_would_block(buffer->pool[buffer->current_item] //we pick one of the other pool items, copy the entirety of the current item //into that item, and then the new subdata if(write_would_block(&buffer->pool[buffer->current_item])) { //pick a non busy entry from the pool; uint32_t i; for(i = 0; i< GLXX_BUFFER_POOL_SIZE; i++) { if(i!=(uint32_t)buffer->current_item && !write_would_block(&buffer->pool[i])) break; } if(i<GLXX_BUFFER_POOL_SIZE) { //found one //copy existing data into this new item assuming alloc succeeds uint32_t existing_size = mem_get_size(buffer->pool[buffer->current_item].mh_storage); bool ok; void * existing_data = mem_lock(buffer->pool[buffer->current_item].mh_storage); ok = glxx_buffer_inner_data(&buffer->pool[i],existing_size,existing_data,true); mem_unlock(buffer->pool[buffer->current_item].mh_storage); if(ok) { #ifdef __VIDEOCORE4__ //unretain current one, so when fixer also unretains, retain count will fall to 0 mem_unretain(buffer->pool[buffer->current_item].mh_storage); //retain new one if(buffer->pool[i].mh_storage!=MEM_ZERO_SIZE_HANDLE) mem_retain(buffer->pool[i].mh_storage); #endif buffer->current_item = i; } } //else stick with the existing and wait } glxx_buffer_inner_subdata(&buffer->pool[buffer->current_item],offset,size,data); #ifdef REQUIRE_MAX_INDEX_CHECK buffer->size_used_for_max = 0; #endif }
static VALUE ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) { SSL *ssl; int ilen, nread = 0; VALUE len, str; rb_io_t *fptr; rb_scan_args(argc, argv, "11", &len, &str); ilen = NUM2INT(len); if(NIL_P(str)) str = rb_str_new(0, ilen); else{ StringValue(str); rb_str_modify(str); rb_str_resize(str, ilen); } if(ilen == 0) return str; Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { if(!nonblock && SSL_pending(ssl) <= 0) rb_thread_wait_fd(FPTR_TO_FD(fptr)); for (;;){ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); switch(ssl_get_error(ssl, nread)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_ZERO_RETURN: rb_eof_error(); case SSL_ERROR_WANT_WRITE: write_would_block(nonblock); rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: read_would_block(nonblock); rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_read:"); } } } else { ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); rb_warning("SSL session is not started yet."); return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); } end: rb_str_set_len(str, nread); OBJ_TAINT(str); return str; }
bool glxx_buffer_data(GLXX_BUFFER_T *buffer, int32_t size, const void *data, GLenum usage) { vcos_assert(size >= 0); if(write_would_block(&buffer->pool[buffer->current_item])) { //pick a non busy entry from the pool; uint32_t i; for(i = 0; i< GLXX_BUFFER_POOL_SIZE; i++) { if(i!=(uint32_t)buffer->current_item && !write_would_block(&buffer->pool[i])) break; } if(i<GLXX_BUFFER_POOL_SIZE) { //found one #ifdef __VIDEOCORE4__ //unretain current one, so when fixer also unretains, retain count will fall to 0 mem_unretain(buffer->pool[buffer->current_item].mh_storage); //retain new one if(buffer->pool[i].mh_storage!=MEM_ZERO_SIZE_HANDLE) mem_retain(buffer->pool[i].mh_storage); #endif buffer->current_item = i; } //else stick with the existing and wait } if(!glxx_buffer_inner_data(&buffer->pool[buffer->current_item],size,data,false)) return false; //successfuly allocated memory and copied data buffer->usage = usage; #ifdef REQUIRE_MAX_INDEX_CHECK buffer->size_used_for_max = 0; #endif return true; }
static VALUE ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock) { SSL *ssl; int nwrite = 0; rb_io_t *fptr; StringValue(str); Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { for (;;){ nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); switch(ssl_get_error(ssl, nwrite)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_WANT_WRITE: write_would_block(nonblock); rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: read_would_block(nonblock); rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if (errno) rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_write:"); } } } else { ID id_syswrite = rb_intern("syswrite"); rb_warning("SSL session is not started yet."); return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); } end: return INT2NUM(nwrite); }
static VALUE ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock) { SSL *ssl; rb_io_t *fptr; int ret, ret2; VALUE cb_state; rb_ivar_set(self, ID_callback_state, Qnil); Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); for(;;){ ret = func(ssl); cb_state = rb_ivar_get(self, ID_callback_state); if (!NIL_P(cb_state)) rb_jump_tag(NUM2INT(cb_state)); if (ret > 0) break; switch((ret2 = ssl_get_error(ssl, ret))){ case SSL_ERROR_WANT_WRITE: write_would_block(nonblock); rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: read_would_block(nonblock); rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if (errno) rb_sys_fail(funcname); ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); default: ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); } } return self; }