From 7be6a8fc3a9c35437c75d0b77b8cec5b0cda043e Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Tue, 6 Nov 2012 21:49:55 +0400 Subject: [PATCH] YaGL: Fixed for khronos GLESv2 test: programs and shaders must be in same namespace YaGL: Fixed for khronos GLESv2 test: n < 0 checks added to glGenXXX YaGL: Fixed for khronos GLESv2 test: namespace local name generation must take user binded names into account --- hw/yagl_apis/gles/yagl_host_gles_calls.c | 10 + hw/yagl_apis/gles2/yagl_gles2_program.c | 1 + hw/yagl_apis/gles2/yagl_gles2_program.h | 11 +- hw/yagl_apis/gles2/yagl_gles2_shader.c | 1 + hw/yagl_apis/gles2/yagl_gles2_shader.h | 15 +- hw/yagl_apis/gles2/yagl_host_gles2_calls.c | 218 ++++++++++++++++++--- hw/yagl_namespace.c | 25 ++- hw/yagl_sharegroup.c | 27 +++ hw/yagl_sharegroup.h | 11 +- 9 files changed, 273 insertions(+), 46 deletions(-) diff --git a/hw/yagl_apis/gles/yagl_host_gles_calls.c b/hw/yagl_apis/gles/yagl_host_gles_calls.c index d0fba5afd7..86927e352a 100644 --- a/hw/yagl_apis/gles/yagl_host_gles_calls.c +++ b/hw/yagl_apis/gles/yagl_host_gles_calls.c @@ -853,6 +853,11 @@ bool yagl_host_glGenBuffers(GLsizei n, YAGL_GET_CTX(glGenBuffers); + if (n < 0) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + if (!yagl_mem_prepare(ts->mt1, buffers_, n * sizeof(*buffer_names))) { res = false; goto out; @@ -900,6 +905,11 @@ bool yagl_host_glGenTextures(GLsizei n, YAGL_GET_CTX(glGenTextures); + if (n < 0) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + if (!yagl_mem_prepare(ts->mt1, textures_, n * sizeof(*texture_names))) { res = false; goto out; diff --git a/hw/yagl_apis/gles2/yagl_gles2_program.c b/hw/yagl_apis/gles2/yagl_gles2_program.c index ef10d277db..6537e296e4 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_program.c +++ b/hw/yagl_apis/gles2/yagl_gles2_program.c @@ -30,6 +30,7 @@ struct yagl_gles2_program yagl_object_init(&program->base, &yagl_gles2_program_destroy); + program->is_shader = false; program->driver_ps = driver_ps; program->global_name = global_name; diff --git a/hw/yagl_apis/gles2/yagl_gles2_program.h b/hw/yagl_apis/gles2/yagl_gles2_program.h index d4840e3953..ccaca37a08 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_program.h +++ b/hw/yagl_apis/gles2/yagl_gles2_program.h @@ -4,15 +4,22 @@ #include "yagl_types.h" #include "yagl_object.h" -#define YAGL_NS_PROGRAM 5 - struct yagl_gles2_driver_ps; struct yagl_gles2_shader; struct yagl_gles2_program { + /* + * These members must be exactly as in yagl_gles2_shader + * @{ + */ struct yagl_object base; + bool is_shader; + /* + * @} + */ + struct yagl_gles2_driver_ps *driver_ps; yagl_object_name global_name; diff --git a/hw/yagl_apis/gles2/yagl_gles2_shader.c b/hw/yagl_apis/gles2/yagl_gles2_shader.c index 87424d7fba..808be060b1 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_shader.c +++ b/hw/yagl_apis/gles2/yagl_gles2_shader.c @@ -39,6 +39,7 @@ struct yagl_gles2_shader yagl_object_init(&shader->base, &yagl_gles2_shader_destroy); + shader->is_shader = true; shader->driver_ps = driver_ps; shader->global_name = global_name; shader->type = type; diff --git a/hw/yagl_apis/gles2/yagl_gles2_shader.h b/hw/yagl_apis/gles2/yagl_gles2_shader.h index 10d1da615f..32a2ff7edc 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_shader.h +++ b/hw/yagl_apis/gles2/yagl_gles2_shader.h @@ -4,14 +4,27 @@ #include "yagl_types.h" #include "yagl_object.h" -#define YAGL_NS_SHADER 4 +/* + * Programs and shaders share the same namespace, + * pretty clumsy! + */ +#define YAGL_NS_SHADER_PROGRAM 4 struct yagl_gles2_driver_ps; struct yagl_gles2_shader { + /* + * These members must be exactly as in yagl_gles2_program + * @{ + */ struct yagl_object base; + bool is_shader; + /* + * @} + */ + struct yagl_gles2_driver_ps *driver_ps; yagl_object_name global_name; diff --git a/hw/yagl_apis/gles2/yagl_host_gles2_calls.c b/hw/yagl_apis/gles2/yagl_host_gles2_calls.c index 0115cc1048..240c10cef9 100644 --- a/hw/yagl_apis/gles2/yagl_host_gles2_calls.c +++ b/hw/yagl_apis/gles2/yagl_host_gles2_calls.c @@ -219,21 +219,31 @@ bool yagl_host_glAttachShader(GLuint program, YAGL_GET_CTX(glAttachShader); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (!yagl_gles2_program_attach_shader(program_obj, shader_obj, shader)) { YAGL_SET_ERR(GL_INVALID_OPERATION); goto out; @@ -257,13 +267,18 @@ bool yagl_host_glBindAttribLocation(GLuint program, YAGL_GET_CTX(glBindAttribLocation); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (name_) { name = yagl_mem_get_string(gles2_api_ts->ts, name_); if (!name) { @@ -431,13 +446,18 @@ bool yagl_host_glCompileShader(GLuint shader) YAGL_GET_CTX(glCompileShader); shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + yagl_gles2_shader_compile(shader_obj); out: @@ -460,7 +480,7 @@ bool yagl_host_glCreateProgram(GLuint* retval) goto out; } - *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_PROGRAM, &program->base); + *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER_PROGRAM, &program->base); out: yagl_gles2_program_release(program); @@ -484,7 +504,7 @@ bool yagl_host_glCreateShader(GLuint* retval, goto out; } - *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER, &shader->base); + *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER_PROGRAM, &shader->base); out: yagl_gles2_shader_release(shader); @@ -534,13 +554,35 @@ out: bool yagl_host_glDeleteProgram(GLuint program) { + struct yagl_gles2_program *program_obj = NULL; + YAGL_GET_CTX(glDeleteProgram); + if (program == 0) { + goto out; + } + + program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, + YAGL_NS_SHADER_PROGRAM, program); + + if (!program_obj) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + + if (program_obj->is_shader) { + goto out; + } + yagl_gles2_context_unuse_program(ctx, program); - yagl_sharegroup_remove(ctx->sg, - YAGL_NS_PROGRAM, - program); + yagl_sharegroup_remove_check(ctx->sg, + YAGL_NS_SHADER_PROGRAM, + program, + &program_obj->base); + +out: + yagl_gles2_program_release(program_obj); return true; } @@ -587,11 +629,33 @@ out: bool yagl_host_glDeleteShader(GLuint shader) { + struct yagl_gles2_shader *shader_obj = NULL; + YAGL_GET_CTX(glDeleteShader); - yagl_sharegroup_remove(ctx->sg, - YAGL_NS_SHADER, - shader); + if (shader == 0) { + goto out; + } + + shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, + YAGL_NS_SHADER_PROGRAM, shader); + + if (!shader_obj) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + + if (!shader_obj->is_shader) { + goto out; + } + + yagl_sharegroup_remove_check(ctx->sg, + YAGL_NS_SHADER_PROGRAM, + shader, + &shader_obj->base); + +out: + yagl_gles2_shader_release(shader_obj); return true; } @@ -605,21 +669,31 @@ bool yagl_host_glDetachShader(GLuint program, YAGL_GET_CTX(glDetachShader); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (!yagl_gles2_program_detach_shader(program_obj, shader_obj, shader)) { YAGL_SET_ERR(GL_INVALID_OPERATION); goto out; @@ -781,6 +855,11 @@ bool yagl_host_glGenFramebuffers(GLsizei n, YAGL_GET_CTX(glGenFramebuffers); + if (n < 0) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + if (!yagl_mem_prepare(gles2_api_ts->ts->mt1, framebuffers_, n * sizeof(*framebuffer_names))) { res = false; goto out; @@ -828,6 +907,11 @@ bool yagl_host_glGenRenderbuffers(GLsizei n, YAGL_GET_CTX(glGenRenderbuffers); + if (n < 0) { + YAGL_SET_ERR(GL_INVALID_VALUE); + goto out; + } + if (!yagl_mem_prepare(gles2_api_ts->ts->mt1, renderbuffers_, n * sizeof(*renderbuffer_names))) { res = false; goto out; @@ -883,13 +967,18 @@ bool yagl_host_glGetActiveAttrib(GLuint program, YAGL_GET_CTX(glGetActiveAttrib); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (bufsize > 0) { name = yagl_gles_context_malloc(&ctx->base, bufsize); } @@ -953,13 +1042,18 @@ bool yagl_host_glGetActiveUniform(GLuint program, YAGL_GET_CTX(glGetActiveUniform); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (bufsize > 0) { name = yagl_gles_context_malloc(&ctx->base, bufsize); } @@ -1018,13 +1112,18 @@ bool yagl_host_glGetAttachedShaders(GLuint program, YAGL_GET_CTX(glGetAttachedShaders); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (maxcount < 0) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; @@ -1082,13 +1181,18 @@ bool yagl_host_glGetAttribLocation(int* retval, *retval = 0; program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (name_) { name = yagl_mem_get_string(gles2_api_ts->ts, name_); if (!name) { @@ -1164,13 +1268,18 @@ bool yagl_host_glGetProgramiv(GLuint program, } program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (params_) { if (!yagl_mem_get_GLint(gles2_api_ts->ts, params_, ¶ms)) { res = false; @@ -1203,13 +1312,18 @@ bool yagl_host_glGetProgramInfoLog(GLuint program, YAGL_GET_CTX(glGetProgramInfoLog); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (bufsize < 0) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; @@ -1281,13 +1395,18 @@ bool yagl_host_glGetShaderiv(GLuint shader, } shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (params_) { if (!yagl_mem_get_GLint(gles2_api_ts->ts, params_, ¶ms)) { res = false; @@ -1320,13 +1439,18 @@ bool yagl_host_glGetShaderInfoLog(GLuint shader, YAGL_GET_CTX(glGetShaderInfoLog); shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (bufsize < 0) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; @@ -1418,13 +1542,18 @@ bool yagl_host_glGetShaderSource(GLuint shader, YAGL_GET_CTX(glGetShaderSource); shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (bufsize < 0) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; @@ -1491,13 +1620,18 @@ bool yagl_host_glGetUniformLocation(int* retval, *retval = 0; program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + if (name_) { name = yagl_mem_get_string(gles2_api_ts->ts, name_); if (!name) { @@ -1670,10 +1804,10 @@ bool yagl_host_glIsProgram(GLboolean* retval, *retval = GL_FALSE; program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (program_obj) { - *retval = GL_TRUE; + *retval = program_obj->is_shader ? GL_FALSE : GL_TRUE; } yagl_gles2_program_release(program_obj); @@ -1712,10 +1846,10 @@ bool yagl_host_glIsShader(GLboolean* retval, *retval = GL_FALSE; shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (shader_obj) { - *retval = GL_TRUE; + *retval = shader_obj->is_shader ? GL_TRUE : GL_FALSE; } yagl_gles2_shader_release(shader_obj); @@ -1730,13 +1864,18 @@ bool yagl_host_glLinkProgram(GLuint program) YAGL_GET_CTX(glLinkProgram); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + yagl_gles2_program_link(program_obj); out: @@ -1803,13 +1942,18 @@ bool yagl_host_glShaderSource(GLuint shader, } shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_SHADER, shader); + YAGL_NS_SHADER_PROGRAM, shader); if (!shader_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (!shader_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + string_ptrs = g_malloc(count * sizeof(*string_ptrs)); if (!yagl_mem_get(gles2_api_ts->ts, string_, count * sizeof(*string_ptrs), string_ptrs)) { res = false; @@ -2293,12 +2437,17 @@ bool yagl_host_glUseProgram(GLuint program) if (program != 0) { program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } } yagl_gles2_context_use_program(ctx, program); @@ -2319,13 +2468,18 @@ bool yagl_host_glValidateProgram(GLuint program) YAGL_GET_CTX(glValidateProgram); program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg, - YAGL_NS_PROGRAM, program); + YAGL_NS_SHADER_PROGRAM, program); if (!program_obj) { YAGL_SET_ERR(GL_INVALID_VALUE); goto out; } + if (program_obj->is_shader) { + YAGL_SET_ERR(GL_INVALID_OPERATION); + goto out; + } + yagl_gles2_program_validate(program_obj); out: diff --git a/hw/yagl_namespace.c b/hw/yagl_namespace.c index dc83dba941..37373b7143 100644 --- a/hw/yagl_namespace.c +++ b/hw/yagl_namespace.c @@ -77,20 +77,25 @@ yagl_object_name yagl_namespace_add(struct yagl_namespace *ns, struct yagl_namespace_entry *item = g_malloc0(sizeof(struct yagl_namespace_entry)); - if (!ns->next_local_name) { - /* - * 0 names are invalid. - */ - - ++ns->next_local_name; - } + yagl_object_acquire(obj); - item->local_name = ns->next_local_name++; item->obj = obj; - yagl_object_acquire(obj); + do { + if (!ns->next_local_name) { + /* + * 0 names are invalid. + */ + + ++ns->next_local_name; + } + + item->local_name = ns->next_local_name++; - yagl_avl_assert_insert(ns->entries, item); + /* + * Find a free local name. + */ + } while (yagl_avl_insert(ns->entries, item)); return item->local_name; } diff --git a/hw/yagl_sharegroup.c b/hw/yagl_sharegroup.c index 0b1fce3011..88ff7ddf68 100644 --- a/hw/yagl_sharegroup.c +++ b/hw/yagl_sharegroup.c @@ -158,6 +158,33 @@ void yagl_sharegroup_remove(struct yagl_sharegroup *sg, yagl_sharegroup_release_objects(&tmp); } +void yagl_sharegroup_remove_check(struct yagl_sharegroup *sg, + int ns, + yagl_object_name local_name, + struct yagl_object *obj) +{ + struct yagl_object_list tmp; + struct yagl_object *actual_obj; + + QLIST_INIT(&tmp); + + qemu_mutex_lock(&sg->mutex); + + yagl_sharegroup_reap_list_move(sg, &tmp); + + actual_obj = yagl_namespace_acquire(&sg->namespaces[ns], local_name); + + if (actual_obj == obj) { + yagl_namespace_remove(&sg->namespaces[ns], local_name); + } + + yagl_object_release(actual_obj); + + qemu_mutex_unlock(&sg->mutex); + + yagl_sharegroup_release_objects(&tmp); +} + struct yagl_object *yagl_sharegroup_acquire_object(struct yagl_sharegroup *sg, int ns, yagl_object_name local_name) diff --git a/hw/yagl_sharegroup.h b/hw/yagl_sharegroup.h index 170c3cf13d..b06ee87292 100644 --- a/hw/yagl_sharegroup.h +++ b/hw/yagl_sharegroup.h @@ -7,7 +7,7 @@ #include "qemu-thread.h" #include "qemu-queue.h" -#define YAGL_NUM_NAMESPACES 6 +#define YAGL_NUM_NAMESPACES 5 struct yagl_sharegroup_reap_entry; @@ -97,6 +97,15 @@ void yagl_sharegroup_remove(struct yagl_sharegroup *sg, int ns, yagl_object_name local_name); +/* + * Same as 'yagl_sharegroup_remove', but removes only if and object + * behind 'local_name' is 'obj' + */ +void yagl_sharegroup_remove_check(struct yagl_sharegroup *sg, + int ns, + yagl_object_name local_name, + struct yagl_object *obj); + /* * Acquires an object by its local name. Be sure to release the object when * you're done. -- 2.34.1