/* attach worker to the shared memory segment, read the job structure */ static void initialize_worker(uint32 segment) { dsm_segment *seg; ResourceOwner old, tmp; /* Connect to dynamic shared memory segment. * * In order to attach a dynamic shared memory segment, we need a * resource owner. We cannot to StartTransactionCommand here, since * we haven't yet attached to the database: to do this, we need to * fetch information about connection properties from the shared * memory segment. */ old = CurrentResourceOwner; CurrentResourceOwner = ResourceOwnerCreate(NULL, "Background Worker"); seg = dsm_attach(segment); if (seg == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("unable to map dynamic shared memory segment"))); dsm_pin_mapping(seg); tmp = CurrentResourceOwner; CurrentResourceOwner = old; ResourceOwnerDelete(tmp); job = palloc(sizeof(JobDesc)); /* copy the arguments from shared memory segment */ memcpy(job, dsm_segment_address(seg), sizeof(JobDesc)); /* and detach it right away */ dsm_detach(seg); Assert(job->magic == JOB_MAGIC); job_run_function.schema = quote_identifier(job->schemaname); job_run_function.name = quote_identifier("run_job"); }
/* * Initialize dsm segment. Returns true if new segment was created and * false if attached to existing segment */ bool init_dsm_segment(size_t blocks_count, size_t block_size) { bool ret; /* if there is already an existing segment then attach to it */ if (dsm_cfg->segment_handle != 0) { ret = false; segment = dsm_attach(dsm_cfg->segment_handle); } /* * If segment hasn't been created yet or has already been destroyed * (it happens when last session detaches segment) then create new one */ if (dsm_cfg->segment_handle == 0 || segment == NULL) { /* create segment */ segment = dsm_create(block_size * blocks_count, 0); dsm_cfg->segment_handle = dsm_segment_handle(segment); dsm_cfg->first_free = 0; dsm_cfg->block_size = block_size; dsm_cfg->blocks_count = blocks_count; init_dsm_table(block_size, 0, dsm_cfg->blocks_count); ret = true; } /* * Keep mapping till the end of the session. Otherwise it would be * destroyed by the end of transaction */ dsm_pin_mapping(segment); return ret; }